mirror of
https://github.com/kemko/nomad.git
synced 2026-01-01 16:05:42 +03:00
docs: update Consul and Vault integration (#19424)
This commit is contained in:
@@ -6,11 +6,16 @@ description: Learn about Nomad's workload identity feature
|
||||
|
||||
# Workload Identity
|
||||
|
||||
Every workload running in Nomad is given an identity. When an [allocation][] is
|
||||
accepted by the [plan applier][], the leader generates a Workload Identity for
|
||||
each task in the allocation. This workload identity is a [JSON Web Token
|
||||
(JWT)][] that has been signed by the leader's keyring. The workload identity
|
||||
includes the following identity claims:
|
||||
Every workload running in Nomad is given a default identity. When an
|
||||
[allocation][] is accepted by the [plan applier][], the leader generates a
|
||||
Workload Identity for each task in the allocation. This workload identity is a
|
||||
[JSON Web Token (JWT)][] that has been signed by the leader's keyring.
|
||||
Additional workload identities may be defined in tasks and services using the
|
||||
[`identity`][identity-block] block.
|
||||
|
||||
## Workload Identity Claims
|
||||
|
||||
Nomad workload identity for tasks include the following identity claims.
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -21,7 +26,48 @@ includes the following identity claims:
|
||||
}
|
||||
```
|
||||
|
||||
## Using Workload Identity
|
||||
Workload identities for Consul services have a claim with the service name
|
||||
instead of the task name.
|
||||
|
||||
```json
|
||||
{
|
||||
"nomad_namespace": "default",
|
||||
"nomad_job_id": "example",
|
||||
"nomad_allocation_id": "8623ac7a-28ba-20c3-24a6-e615a39bbbf3",
|
||||
"nomad_service": "example-cache-redis"
|
||||
}
|
||||
```
|
||||
|
||||
### Nomad Enterprise <EnterpriseAlert inline />
|
||||
|
||||
In Nomad Enterprise, tasks and services with a [`consul`][jobspec_consul] block
|
||||
that defines a [`namespace`][jobspec_consul_ns] value, or inside a `group`
|
||||
block that does it, have an additional claim called `consul_namespace`.
|
||||
|
||||
```json
|
||||
{
|
||||
"consul_namespace": "prod",
|
||||
"nomad_namespace": "default",
|
||||
"nomad_job_id": "example",
|
||||
"nomad_allocation_id": "8623ac7a-28ba-20c3-24a6-e615a39bbbf3",
|
||||
"nomad_service": "example-cache-redis"
|
||||
}
|
||||
```
|
||||
|
||||
Similarly, tasks with a [`vault.namespace`][] value have the additional claim
|
||||
`vault_namespace`.
|
||||
|
||||
```json
|
||||
{
|
||||
"nomad_namespace": "default",
|
||||
"nomad_job_id": "example",
|
||||
"nomad_allocation_id": "8623ac7a-28ba-20c3-24a6-e615a39bbbf3",
|
||||
"nomad_service": "example-cache-redis"
|
||||
"vault_namespace": "prod",
|
||||
}
|
||||
```
|
||||
|
||||
## Workload Identity for Nomad
|
||||
|
||||
While Nomad always creates and uses workload identities internally, the JWT is
|
||||
not exposed to tasks by default.
|
||||
@@ -43,7 +89,7 @@ task "example" {
|
||||
}
|
||||
```
|
||||
|
||||
## Default Workload ACL Policy
|
||||
### Default Workload ACL Policy
|
||||
|
||||
By default, a Workload Identity has access to a implicit ACL policy. This policy
|
||||
grants access to Nomad Variables associated with the job, group, and task, as
|
||||
@@ -51,7 +97,7 @@ described in [Task Access to Variables][]. The implicit policy also allows
|
||||
access to list or read any Nomad service registration as with the [List Services
|
||||
API][] or [Read Service API][].
|
||||
|
||||
## Workload Associated ACL Policies
|
||||
### Workload Associated ACL Policies
|
||||
|
||||
You can associate additional ACL policies with workload identities by passing
|
||||
the `-job`, `-group`, and `-task` flags to `nomad acl policy apply`. When Nomad
|
||||
@@ -98,13 +144,21 @@ nomad acl policy apply \
|
||||
redis-policy ./policy.hcl
|
||||
```
|
||||
|
||||
## Task API
|
||||
### Task API
|
||||
|
||||
It can be convenient to combine workload identity with Nomad's [Task API]
|
||||
[taskapi] for enabling tasks to access the Nomad API.
|
||||
|
||||
## Workload Identity for Consul and Vault
|
||||
|
||||
Consul and Vault can be configured to accept workload identities from Nomad for
|
||||
authentication. Refer to the [Consul][consul_int] and [Vault][vault_int]
|
||||
integration pages for more information.
|
||||
|
||||
[allocation]: /nomad/docs/concepts/architecture#allocation
|
||||
[identity-block]: /nomad/docs/job-specification/identity
|
||||
[jobspec_consul]: /nomad/docs/job-specification/consul
|
||||
[jobspec_consul_ns]: /nomad/docs/job-specification/consul#namespace
|
||||
[plan applier]: /nomad/docs/concepts/scheduling/scheduling
|
||||
[JSON Web Token (JWT)]: https://datatracker.ietf.org/doc/html/rfc7519
|
||||
[Task Access to Variables]: /nomad/docs/concepts/variables#task-access-to-variables
|
||||
@@ -112,3 +166,5 @@ It can be convenient to combine workload identity with Nomad's [Task API]
|
||||
[Read Service API]: /nomad/api-docs/services#read-service
|
||||
[windows]: https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/
|
||||
[taskapi]: /nomad/api-docs/task-api
|
||||
[consul_int]: /nomad/docs/integrations/consul-integration
|
||||
[vault_int]: /nomad/docs/integrations/vault-integration
|
||||
|
||||
@@ -1,391 +0,0 @@
|
||||
---
|
||||
layout: docs
|
||||
page_title: Consul Integration
|
||||
description: Learn how to integrate Nomad with Consul and add service discovery to jobs
|
||||
---
|
||||
|
||||
# Consul Integration
|
||||
|
||||
[Consul][] is a tool for discovering and configuring services in your
|
||||
infrastructure. Consul's key features include service discovery, health checking,
|
||||
a KV store, and robust support for multi-datacenter deployments. Nomad's integration
|
||||
with Consul enables automatic clustering, built-in service registration, and
|
||||
dynamic rendering of configuration files and environment variables. The sections
|
||||
below describe the integration in more detail.
|
||||
|
||||
## Configuration
|
||||
|
||||
In order to use Consul with Nomad, you will need to configure and install Consul
|
||||
on your nodes alongside Nomad, or schedule it as a system job. Nomad does not
|
||||
run Consul for you.
|
||||
|
||||
To enable Consul integration, please refer to the [Nomad agent Consul
|
||||
configuration][] documentation.
|
||||
|
||||
## Automatic Clustering with Consul
|
||||
|
||||
Nomad servers and clients will be automatically informed of each other's
|
||||
existence when a running Consul cluster already exists and the Consul agent is
|
||||
installed and configured on each host. Please refer to the [Automatic Clustering
|
||||
with Consul][] guide for more information.
|
||||
|
||||
## Service Discovery
|
||||
|
||||
Nomad schedules workloads of various types across a cluster of generic hosts.
|
||||
Because of this, placement is not known in advance and you will need to use
|
||||
service discovery to connect tasks to other services deployed across your
|
||||
cluster. Nomad integrates with Consul to provide service discovery and
|
||||
monitoring.
|
||||
|
||||
To configure a job to register with service discovery, please refer to the
|
||||
[`service` job specification documentation][service].
|
||||
|
||||
## Dynamic Configuration
|
||||
|
||||
Nomad's job specification includes a [`template` block][] that uses a Consul
|
||||
ecosystem tool called [Consul Template][]. This mechanism creates a convenient
|
||||
way to ship configuration files that are populated from environment variables,
|
||||
Consul data, Vault secrets, or just general configurations within a Nomad task.
|
||||
|
||||
For more information on Nomad's template block and how it leverages Consul
|
||||
Template, please see the [`template` job specification documentation][].
|
||||
|
||||
## Using Nomad Workload Identity with Consul
|
||||
|
||||
Starting in Nomad 1.7, Nomad clients will use a task or service's [Workload
|
||||
Identity][] to authenticate to Consul and obtain a Consul token specific to the
|
||||
service or task. When using Workload Identity you will no longer need to pass in
|
||||
a Consul token to submit a job.
|
||||
|
||||
<Note>
|
||||
|
||||
For Consul Enterprise users that would like to use Consul Namespaces, currently
|
||||
the only supported way of namespacing ACL objects is creating auth methods and
|
||||
binding rules in the `default` namespace, and roles and policies in the desired
|
||||
Consul namespace. The reason for this is simplicity: users wanting complete
|
||||
namespacing of all ACL objects would be required to create an auth method and
|
||||
binding rule per namespace. In the future we plan on adding such a possibility,
|
||||
but currently such a configuration is not supported by Nomad.
|
||||
|
||||
</Note>
|
||||
|
||||
### Configuring Consul Authentication
|
||||
|
||||
Create a configuration file for a Consul [JWT Auth Method][]. The `JWKSURL`
|
||||
field should point to all the Nomad servers; you should use a proxy or DNS A
|
||||
Record to ensure that requests can go to any server in the cluster. The
|
||||
remaining fields are required to match those shown here.
|
||||
|
||||
<Tabs>
|
||||
<Tab heading="Consul Community Edition">
|
||||
|
||||
```json
|
||||
{
|
||||
"JWKSURL": "https://nomad.example.com:4646/.well-known/jwks.json",
|
||||
"JWTSupportedAlgs": ["RS256"],
|
||||
"BoundAudiences": ["consul.io"],
|
||||
"ClaimMappings": {
|
||||
"nomad_namespace": "nomad_namespace",
|
||||
"nomad_job_id": "nomad_job_id",
|
||||
"nomad_task": "nomad_task",
|
||||
"nomad_service": "nomad_service"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab heading="Consul Enterprise">
|
||||
|
||||
```json
|
||||
{
|
||||
"JWKSURL": "https://nomad.example.com:4646/.well-known/jwks.json",
|
||||
"JWTSupportedAlgs": ["RS256"],
|
||||
"BoundAudiences": ["consul.io"],
|
||||
"ClaimMappings": {
|
||||
"consul_namespace": "consul_namespace",
|
||||
"nomad_namespace": "nomad_namespace",
|
||||
"nomad_job_id": "nomad_job_id",
|
||||
"nomad_task": "nomad_task",
|
||||
"nomad_service": "nomad_service"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
<Note>
|
||||
|
||||
If you're using an https endpoint on Nomad server itself for JWKS, your server
|
||||
must be configured with `tls.verify_https_client = false`, because currently
|
||||
there is no way to provide Nomad certificates to Consul (or Vault) clients. If
|
||||
you want to use mTLS, which is the recommended practice, you need to terminate
|
||||
TLS before the requests reach Nomad JWKS endpoint.
|
||||
|
||||
</Note>
|
||||
|
||||
Using that configuration file, you'll create a Consul Auth Method named
|
||||
`nomad-workloads`, which controls:
|
||||
|
||||
* Authentication for Service Identity tokens used to register services and
|
||||
configure Consul Connect.
|
||||
|
||||
* Access to reading service data and Consul KV for your jobs' `template`
|
||||
blocks.
|
||||
|
||||
The auth method will have two binding rules attached: one mapping Nomad
|
||||
`service` blocks to Consul services, and one mapping Nomad namespaces or your
|
||||
job IDs to Consul Roles.
|
||||
|
||||
<Note>
|
||||
|
||||
Nomad also supports having separate auth methods for services and tasks, for
|
||||
additional flexibility. Consult [`service_auth_method`] and [`task_auth_method`]
|
||||
configuration parameters documentation.
|
||||
|
||||
</Note>
|
||||
|
||||
#### Auth Method and Binding Rules for Services and Templates
|
||||
|
||||
Using the configuration file shown above, create a Consul Auth Method to
|
||||
support Nomad workloads. Note that you should not set the `-max-token-ttl` flag
|
||||
for Consul Auth Methods used for Nomad.
|
||||
|
||||
<Tabs>
|
||||
<Tab heading="Consul Community Edition">
|
||||
|
||||
In Consul Community Edition, you'll always bind to the default Consul namespace.
|
||||
|
||||
```shell-session
|
||||
$ consul acl auth-method create \
|
||||
-name 'nomad-workloads' \
|
||||
-type jwt \
|
||||
-description 'login method for Nomad workloads' \
|
||||
-format json \
|
||||
-namespace-rule-selector='' \
|
||||
-config "@consul-auth-method-config.json"
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab heading="Consul Enterprise">
|
||||
|
||||
In Consul Enterprise, you'll map the auth method to a Consul namespace.
|
||||
|
||||
```shell-session
|
||||
$ consul acl auth-method create \
|
||||
-name 'nomad-workloads' \
|
||||
-type jwt \
|
||||
-description 'login method for Nomad workloads' \
|
||||
-format json \
|
||||
-namespace-rule-selector='' \
|
||||
-namespace-rule-bind-namespace='${value.nomad_namespace}' \
|
||||
-config "@consul-auth-method-config.json"
|
||||
```
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
Create a [Consul Binding Rule][] that maps the Nomad Workload Identity to the
|
||||
Consul Service Identity.
|
||||
|
||||
```shell-session
|
||||
$ consul acl binding-rule create \
|
||||
-method 'nomad-workloads' \
|
||||
-description 'binding rule for Nomad workload identities (WI)' \
|
||||
-bind-type service \
|
||||
-bind-name '${value.nomad_service}' \
|
||||
-selector '"nomad_service" in value'
|
||||
```
|
||||
|
||||
Next, create a Consul Binding Rule that maps Nomad namespaces to Consul Roles:
|
||||
|
||||
```shell-session
|
||||
$ consul acl binding-rule create \
|
||||
-method 'nomad-workloads' \
|
||||
-description 'binding rule for Nomad template workload identities (WI)' \
|
||||
-bind-type role \
|
||||
-bind-name 'nomad-${value.nomad_namespace}-tasks' \
|
||||
-selector '"nomad_service" not in value'
|
||||
```
|
||||
|
||||
#### Role for Templates
|
||||
|
||||
For each Nomad namespace that you want to grant access to Consul, create a
|
||||
[Consul role][] with a name like `nomad-$nomadNamespace-tasks` to match the
|
||||
binding rule you created previously. For example, for the Nomad namespace named
|
||||
`prod` you'll create the following Consul role.
|
||||
|
||||
```shell-session
|
||||
$ consul acl role create \
|
||||
-name "nomad-prod-tasks" \
|
||||
-description "role for Nomad production workloads with templates" \
|
||||
-policy-name "example-policy"
|
||||
```
|
||||
|
||||
The policy you assign to the role should have sufficient `service:read` and
|
||||
`kv:read` permissions. An example policy might look like the following.
|
||||
|
||||
```hcl
|
||||
key_prefix "" {
|
||||
policy = "read"
|
||||
}
|
||||
|
||||
service_prefix "" {
|
||||
policy = "read"
|
||||
}
|
||||
```
|
||||
|
||||
The binding rule you created above for Nomad namespaces will map workloads to
|
||||
the role with this policy.
|
||||
|
||||
## Authenticating Without Workload Identity (Legacy)
|
||||
|
||||
If [Consul ACLs][consul_acls] are enabled, the [`allow_unauthenticated`][]
|
||||
configuration parameter will control whether a Consul token will be required
|
||||
when submitting a job with Consul namespace configured. The provided Consul
|
||||
token must belong to the correct namespace, and must be backed by a Consul ACL
|
||||
Policy with sufficient `service:write` and `kv:read` permissions. An example
|
||||
policy might look like the following.
|
||||
|
||||
```hcl
|
||||
key_prefix "" {
|
||||
policy = "read"
|
||||
}
|
||||
|
||||
service_prefix "" {
|
||||
policy = "write"
|
||||
}
|
||||
```
|
||||
|
||||
<Note>
|
||||
|
||||
This legacy workflow will be removed in Nomad 1.9. Before upgrading to Nomad 1.9
|
||||
you will need to have configured authentication with Consul as described in
|
||||
[Configuring Consul Authentication](#configuring-consul-authentication).
|
||||
|
||||
</Note>
|
||||
|
||||
## Migrating to Using Workload Identity with Consul
|
||||
|
||||
Migrating from the legacy (pre-1.7) workflow where workload use the agent's
|
||||
Consul token requires configuation on your Consul cluster and your Nomad server
|
||||
agents. It does not require updating your running Nomad jobs. To migrate:
|
||||
|
||||
* Create the Consul auth method and binding rules on your Consul cluster.
|
||||
* Enable [`consul.service_identity`][] blocks in your Nomad server agent configurations.
|
||||
* Enable [`consul.task_identity`][] blocks in your Nomad server agent configurations.
|
||||
* (Optionally) add [`identity`][] blocks to your jobs if you want to use a
|
||||
different identity because of how your auth method and binding rules are
|
||||
configured.
|
||||
|
||||
Note that when using Workload Identity you will no longer need to pass in a
|
||||
Consul token to submit a job.
|
||||
|
||||
## Consul Namespaces
|
||||
|
||||
Nomad provides integration with [Consul Namespaces][consul_namespaces] for
|
||||
service registrations specified in `service` blocks and Consul KV reads in
|
||||
`template` blocks.
|
||||
|
||||
By default, Nomad will not specify a Consul namespace on service registrations
|
||||
or KV store reads, which Consul then implicitly resolves to the `"default"`
|
||||
namespace. This default namespace behavior can be modified by setting the
|
||||
[`namespace`][consul_agent_namespace] field in the Nomad agent Consul
|
||||
configuration block.
|
||||
|
||||
For more control over Consul namespaces, Nomad Enterprise supports configuring
|
||||
the Consul [namespace][consul_jobspec_namespace] at the group or task level in
|
||||
the Nomad job spec as well as the [`-consul-namespace`][consul_run_namespace]
|
||||
command line argument for `job run`.
|
||||
|
||||
The Consul namespace used for a set of group or task service registrations
|
||||
within a group, as well as `template` KV store access is determined from the
|
||||
following hierarchy from lowest to highest precedence:
|
||||
|
||||
* Consul default: If no Consul namespace options are configured, Consul will
|
||||
automatically make use of the `"default"` namespace.
|
||||
|
||||
* agent configuration: If the [`namespace`][consul_agent_namespace] Nomad agent
|
||||
Consul configuration parameter is set, this namespace will be used instead of
|
||||
the Consul default.
|
||||
|
||||
* job run command: <EnterpriseAlert inline/> If the
|
||||
[`-consul-namespace`][consul_run_namespace] command line argument is specified
|
||||
on job submission, this namespace will take precedence over the namespace set
|
||||
in Nomad agent configuration.
|
||||
|
||||
* group and task configuration: <EnterpriseAlert inline/> If the group level or
|
||||
task level Consul [namespace field][consul_jobspec_namespace] is configured,
|
||||
this namespace will take precedence over all other options.
|
||||
|
||||
## Assumptions
|
||||
|
||||
* Each Nomad client should have a local Consul agent running on the same host,
|
||||
reachable by Nomad. Nomad clients should never share a Consul agent or talk
|
||||
directly to the Consul servers. Nomad is not compatible with [Consul Data
|
||||
Plane][CDP].
|
||||
|
||||
* The service discovery feature in Nomad depends on operators making sure that
|
||||
the Nomad client can reach the Consul agent.
|
||||
|
||||
* Tasks running inside Nomad also need to reach out to the Consul agent if
|
||||
they want to use any of the Consul APIs. Ex: A task running inside a docker
|
||||
container in the bridge mode won't be able to talk to a Consul Agent running
|
||||
on the loopback interface of the host since the container in the bridge mode
|
||||
has its own network interface and doesn't see interfaces on the global
|
||||
network namespace of the host. There are a couple of ways to solve this, one
|
||||
way is to run the container in the host networking mode, or make the Consul
|
||||
agent listen on an interface in the network namespace of the container.
|
||||
|
||||
* The `consul` binary must be present in Nomad's `$PATH` to run the Envoy
|
||||
proxy sidecar on client nodes.
|
||||
|
||||
* Consul service mesh using network namespaces is only supported on Linux.
|
||||
|
||||
## Compatibility
|
||||
|
||||
Most supported versions of Nomad are compatible with most recent versions of
|
||||
Consul, with some exceptions.
|
||||
|
||||
* Nomad versions 1.6.0+, 1.5.6+, and 1.4.11+ are compatible with any currently
|
||||
supported version of Consul.
|
||||
* Nomad versions 1.4.4 to 1.4.11 and 1.5.0 to 1.5.6 are compatible with any
|
||||
currently supported version of Consul except 1.13.8.
|
||||
* Nomad versions 1.4.0 through 1.4.3 are compatible with Consul versions 1.13.0
|
||||
through 1.13.7, and 1.13.9. Changes to Consul service mesh in version 1.14 are
|
||||
incompatible with Nomad 1.4.3 and earlier.
|
||||
* Nomad is not compatible with Consul Data Plane.
|
||||
|
||||
| | Consul 1.13.0 - 1.13.7 | Consul 1.13.8 | Consul 1.13.9 | Consul 1.14.0+ |
|
||||
|---------------------|------------------------|---------------|---------------|----------------|
|
||||
| Nomad 1.6.0+ | ✅ | ✅ | ✅ | ✅ |
|
||||
| Nomad 1.5.6+ | ✅ | ✅ | ✅ | ✅ |
|
||||
| Nomad 1.5.0-1.5.5 | ✅ | ❌ | ✅ | ✅ |
|
||||
| Nomad 1.4.11-1.4.13 | ✅ | ✅ | ✅ | ✅ |
|
||||
| Nomad 1.4.4-1.4.10 | ✅ | ❌ | ✅ | ✅ |
|
||||
| Nomad 1.4.0-1.4.3 | ✅ | ❌ | ✅ | ❌ |
|
||||
|
||||
|
||||
[Consul]: https://www.consul.io/ "Consul by HashiCorp"
|
||||
[Workload Identity]: /nomad/docs/concepts/workload-identity
|
||||
[Nomad agent Consul configuration]: /nomad/docs/configuration/consul
|
||||
[Automatic Clustering with Consul]: /nomad/tutorials/manage-clusters/clustering
|
||||
[service]: /nomad/docs/job-specification/service "Nomad service Job Specification"
|
||||
[`template` block]: /nomad/docs/job-specification/template
|
||||
[Consul Template]: https://github.com/hashicorp/consul-template
|
||||
[`template` job specification documentation]: /nomad/docs/job-specification/template
|
||||
[consul_namespaces]: /consul/docs/enterprise/namespaces
|
||||
[consul_agent_namespace]: /nomad/docs/configuration/consul#namespace
|
||||
[consul_jobspec_namespace]: /nomad/docs/job-specification/consul#namespace
|
||||
[consul_run_namespace]: /nomad/docs/commands/job/run#consul-namespace
|
||||
[`allow_unauthenticated`]: /nomad/docs/configuration/consul#allow_unauthenticated
|
||||
[consul_acls]: /consul/docs/security/acl
|
||||
[JWT Auth Method]: /consul/docs/security/acl/auth-methods/jwt
|
||||
[Consul Binding Rule]: /consul/api-docs/acl/binding-rules
|
||||
[Consul role]: /consul/docs/security/acl/acl-roles
|
||||
[`consul.service_identity`]: /nomad/docs/configuration/consul#service_identity
|
||||
[`consul.task_identity`]: /nomad/docs/configuration/consul#task_identity
|
||||
[`identity`]: /nomad/docs/job-specification/identity
|
||||
[CDP]: /consul/docs/connect/dataplane
|
||||
[`service_auth_method`]: /nomad/docs/configuration/consul#service_auth_method
|
||||
[`task_auth_method`]: /nomad/docs/configuration/consul#task_auth_method
|
||||
449
website/content/docs/integrations/consul/acl.mdx
Normal file
449
website/content/docs/integrations/consul/acl.mdx
Normal file
@@ -0,0 +1,449 @@
|
||||
---
|
||||
layout: docs
|
||||
page_title: Consul ACL
|
||||
description: Learn how to integrate Nomad with Consul when ACL is enabled.
|
||||
---
|
||||
|
||||
# Consul ACL
|
||||
|
||||
The [Consul ACL][consul_acls] system protects the cluster from unauthorized
|
||||
access. When enabled, both Consul and Nomad must be properly configured in
|
||||
order for their integrations to work.
|
||||
|
||||
Nomad agents must be configured with their own Consul ACL token, and Consul
|
||||
must be configured to accept workload identities from tasks and services
|
||||
running in Nomad.
|
||||
|
||||
## Nomad Agents
|
||||
|
||||
Nomad agents need access to Consul in order to register themselves in the
|
||||
service catalog and discover other Nomad agents via service discovery for
|
||||
automatic clustering. Nomad servers also create [configuration
|
||||
entries][consul_config_entry] for Consul Service Mesh, so the specific
|
||||
permissions vary slightly between Nomad servers and clients. The following
|
||||
Consul ACL policies represent the minimal permissions Nomad servers and clients
|
||||
need.
|
||||
|
||||
<Tabs>
|
||||
<Tab heading="Nomad Servers">
|
||||
|
||||
```hcl
|
||||
agent_prefix "" {
|
||||
policy = "read"
|
||||
}
|
||||
|
||||
node_prefix "" {
|
||||
policy = "read"
|
||||
}
|
||||
|
||||
service_prefix "" {
|
||||
policy = "write"
|
||||
}
|
||||
|
||||
mesh = "write"
|
||||
```
|
||||
|
||||
</Tab>
|
||||
<Tab heading="Nomad Clients">
|
||||
|
||||
```hcl
|
||||
agent_prefix "" {
|
||||
policy = "read"
|
||||
}
|
||||
|
||||
node_prefix "" {
|
||||
policy = "read"
|
||||
}
|
||||
|
||||
service_prefix "" {
|
||||
policy = "write"
|
||||
}
|
||||
```
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## Nomad Workload Identities
|
||||
|
||||
Starting in Nomad 1.7, Nomad clients can use a task or service's [Workload
|
||||
Identity][nomad_wid] to authenticate to Consul and obtain an ACL token specific
|
||||
to the service or task. When using Nomad workload identities, you no longer
|
||||
need to pass in a Consul ACL token to submit a job.
|
||||
|
||||
By default, Nomad does not generate workload identities for services, and tasks
|
||||
only receive an identity that can be used to access data from Nomad itself,
|
||||
such as for reading [Variables][] from a [`template`][] block. To access
|
||||
Consul, jobs must have additional workload identities defined as [`identity`][]
|
||||
blocks.
|
||||
|
||||
To avoid having to add these additional identities to every job, you can
|
||||
configure Nomad servers with the [`consul.service_identity`][] and
|
||||
[`consul.task_identity`][] agent configuration. Upon job registration, the
|
||||
Nomad servers update tasks that have a [`consul`][] or [`template`][] block and
|
||||
services that use the Consul service provider with these default identities.
|
||||
|
||||
You can also specify identities for Consul directly in the job. When provided,
|
||||
they override the Nomad server configuration. Refer to the [Workload Identities
|
||||
for Consul][jobspec_identity_consul] section of the `identity` block
|
||||
documentation for more information.
|
||||
|
||||
### Configuring Consul Authentication
|
||||
|
||||
You must configure Consul so it can receive, validate, and trust workload
|
||||
identities from Nomad. Since they are encoded as [JSON Web Tokens (JWTs)][jwt],
|
||||
you must create a [JWT ACL auth method][consul_jwt_auth_method]. The auth
|
||||
method is an endpoint that Nomad can use to exchange workload identities for
|
||||
Consul ACL tokens.
|
||||
|
||||
Refer to Consul's [Auth Methods Overview][consul_auth_methods] documentation
|
||||
for more information.
|
||||
|
||||
#### Consul Auth Method
|
||||
|
||||
The auth method configuration points to Nomad's [JSON Web Key Set (JWKS)
|
||||
URL][nomad_jwks_url]. Consul servers call this URL to retrieve the public keys
|
||||
Nomad uses to sign workload identities. With these keys, Consul is able to
|
||||
validate their origin and confirm that they were actually created by Nomad.
|
||||
|
||||
<CodeBlockConfig highlight="2" filename="auth-method.json">
|
||||
|
||||
```json
|
||||
{
|
||||
"JWKSURL": "https://nomad.example.com:4646/.well-known/jwks.json",
|
||||
"JWTSupportedAlgs": ["RS256"],
|
||||
"BoundAudiences": ["consul.io"],
|
||||
"ClaimMappings": {
|
||||
"nomad_namespace": "nomad_namespace",
|
||||
"nomad_job_id": "nomad_job_id",
|
||||
"nomad_task": "nomad_task",
|
||||
"nomad_service": "nomad_service"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</CodeBlockConfig>
|
||||
|
||||
The `JWKSURL` address must be reachable by all Consul servers and should
|
||||
resolve to multiple Nomad agents to avoid a single point of failure. Both Nomad
|
||||
servers and clients are able to handle this request.
|
||||
|
||||
Refer to the [Important Considerations About the JWKS
|
||||
URL](#important-considerations-about-the-jwks-url) section for additional
|
||||
information on how to configure the `JWKSURL` value.
|
||||
|
||||
[![Consul Auth Method][img_consul_auth_method]][img_consul_auth_method]
|
||||
|
||||
When an allocation that needs access to Consul starts, the Nomad client running
|
||||
it exchanges the Nomad workload identities for tasks and services for Consul
|
||||
ACL tokens.
|
||||
|
||||
[![Consul JWT Login][img_consul_wid_acl_token]][img_consul_wid_acl_token]
|
||||
|
||||
The auth method also defines the list of authorized audience values, which must
|
||||
have at least one match with the values defined in the Nomad workload identity
|
||||
[`aud`][] parameter. For security reasons, it is recommended to only define a
|
||||
single audience value.
|
||||
|
||||
<CodeBlockConfig highlight="4" filename="auth-method.json">
|
||||
|
||||
```json
|
||||
{
|
||||
"JWKSURL": "http://nomad.example.com:4646/.well-known/jwks.json",
|
||||
"JWTSupportedAlgs": ["RS256"],
|
||||
"BoundAudiences": ["consul.io"],
|
||||
"ClaimMappings": {
|
||||
"nomad_namespace": "nomad_namespace",
|
||||
"nomad_job_id": "nomad_job_id",
|
||||
"nomad_task": "nomad_task",
|
||||
"nomad_service": "nomad_service"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</CodeBlockConfig>
|
||||
|
||||
Nomad workload identities have a set of [claims][nomad_wid_claims] that can be
|
||||
referenced as dynamic values in Consul ACL configuration. The auth method
|
||||
determines which of these claims are made available to the rest of the
|
||||
configuration.
|
||||
|
||||
<CodeBlockConfig highlight="6-9" filename="auth-method.json">
|
||||
|
||||
```json
|
||||
{
|
||||
"JWKSURL": "http://nomad.example.com:4646/.well-known/jwks.json",
|
||||
"JWTSupportedAlgs": ["RS256"],
|
||||
"BoundAudiences": ["consul.io"],
|
||||
"ClaimMappings": {
|
||||
"nomad_namespace": "nomad_namespace",
|
||||
"nomad_job_id": "nomad_job_id",
|
||||
"nomad_task": "nomad_task",
|
||||
"nomad_service": "nomad_service"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</CodeBlockConfig>
|
||||
|
||||
#### Consul Binding Rules
|
||||
|
||||
Consul auth methods use [binding rules][consul_binding_rules] to determine the
|
||||
set of policies applied to the generated ACL token. Nomad workload identities
|
||||
can be used in Consul for two main purpose: registering services and retrieving
|
||||
configuration values and service addresses from Consul using `template` blocks
|
||||
in tasks. Each purpose requires tokens with different permissions so Nomad
|
||||
requires two binding rules.
|
||||
|
||||
The first binding rule associates the Consul ACL token with a [service
|
||||
identity][consul_si], allowing the token to register and manage the lifecyle of
|
||||
a given service. This binding rule is only applied to Nomad workload identities
|
||||
for services because they are the only ones that have a `nomad_service` claim.
|
||||
|
||||
```shell-session
|
||||
$ consul acl binding-rule create \
|
||||
-method 'nomad-workloads' \
|
||||
-bind-type 'service' \
|
||||
-bind-name '${value.nomad_service}' \
|
||||
-selector '"nomad_service" in value'
|
||||
```
|
||||
|
||||
The [`-bind-name`][] flag restricts the token to only be able to modify
|
||||
services with the same name as the one defined in the Nomad workload identity
|
||||
claim. The [`-selector`][] flag ensures this binding rule only applies to
|
||||
workload identities for services.
|
||||
|
||||
The second binding rule associates the Consul ACL token with an [ACL
|
||||
role][consul_acl_role], which is a collection of [ACL
|
||||
policies][consul_acl_policy] that define what the token is authorized to do.
|
||||
This binding rule is applied to Nomad workload identities for tasks to access
|
||||
information from Consul. The exact ACL policy rules will depend on the level of
|
||||
access required by the tasks (typically, accessing service addresses and KV with
|
||||
[`template`][] blocks).
|
||||
|
||||
```shell-session
|
||||
$ consul acl binding-rule create \
|
||||
-method 'nomad-workloads' \
|
||||
-bind-type 'role' \
|
||||
-bind-name 'nomad-tasks-${value.nomad_namespace}' \
|
||||
-selector '"nomad_service" not in value'
|
||||
```
|
||||
|
||||
The `-bind-name` flag defines which role is used for the token. It may
|
||||
reference claim values from the Nomad workload identity to apply different
|
||||
roles to different tasks. Similarly to the binding rule for services, the
|
||||
`-selector` flag ensures this binding rule only applies to workload identities
|
||||
for tasks since they don't have the `nomad_service` claim.
|
||||
|
||||
The overall configuration structure is illustrated in the following diagram.
|
||||
|
||||
[![Consul Auth Overview][img_consul_auth]][img_consul_auth]
|
||||
|
||||
The [`consul.service_auth_method`][] and [`consul.task_auth_method`][]
|
||||
configuration define the auth method used by Nomad to retrieve Consul ACL
|
||||
tokens for services and tasks.
|
||||
|
||||
By default, they follow the structure described above and use a single auth
|
||||
method for both, but it is possible to use two different auth methods, provided
|
||||
the resulting Consul ACL token from each have the expected service identity and
|
||||
role applied.
|
||||
|
||||
#### Consul Namespace Rules <EnterpriseAlert inline />
|
||||
|
||||
Consul Enterprise supports multiple namespaces and Nomad Enterprise allows jobs
|
||||
to use the [`consul.namespace`][] parameter to register services and read KV
|
||||
data from different Consul namespaces.
|
||||
|
||||
In a multi-namespace environment, you should create the auth method and binding
|
||||
rules in the `default` namespace and configure the auth method with a set of
|
||||
[`NamespaceRules`][].
|
||||
|
||||
```shell-session
|
||||
$ consul acl auth-method create \
|
||||
-name 'nomad-workloads' \
|
||||
-type 'jwt' \
|
||||
-config '@auth-method.json' \
|
||||
-namespace-rule-selector '"consul_namespace" in value' \
|
||||
-namespace-rule-bind-namespace '${value.consul_namespace}'
|
||||
```
|
||||
|
||||
Similarly to binding rules, namespace rules have a [`Selector`][] expression to
|
||||
determine when the rule should be applied and a [`BindNamespace`][] value that
|
||||
defines the namespace used.
|
||||
|
||||
In Nomad Enterprise, workload identities for tasks and services placed within
|
||||
the scope of a `consul` block with a `namespace` value, have an additional
|
||||
claim called `consul_namespace` that represents the Consul namespace defined
|
||||
in Nomad for the workload.
|
||||
|
||||
<CodeBlockConfig highlight="9-11" filename="example.nomad.hcl">
|
||||
|
||||
```hcl
|
||||
job "example" {
|
||||
group "cache" {
|
||||
network {
|
||||
port "db" {
|
||||
to = 6379
|
||||
}
|
||||
}
|
||||
|
||||
consul {
|
||||
namespace = "prod"
|
||||
}
|
||||
|
||||
service {
|
||||
port = "db"
|
||||
name = "redis"
|
||||
provider = "consul"
|
||||
}
|
||||
|
||||
task "redis" {
|
||||
driver = "docker"
|
||||
|
||||
config {
|
||||
image = "redis:7"
|
||||
ports = ["db"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</CodeBlockConfig>
|
||||
|
||||
If a `consul` block is not defined, then the workload identity will not have
|
||||
the `consul_namespace` claim, since Nomad is not able to determine which Consul
|
||||
namespace will be used.
|
||||
|
||||
Refer to the [Consul Namespaces][int_consul_ns] section for more information.
|
||||
|
||||
### Important Considerations About the JWKS URL
|
||||
|
||||
The recommended configuration assumes Consul servers are able to connect to
|
||||
Nomad agents (either client or servers) to retrieve the JSON Web Key Set
|
||||
information.
|
||||
|
||||
This section covers additional aspects you should consider depending on how
|
||||
your Consul and Nomad clusters are configured and deployed.
|
||||
|
||||
#### Mutual TLS in Nomad
|
||||
|
||||
It is highly recommended to use [mutual TLS][tutorial_mtls] in production
|
||||
deployments of Nomad. With mTLS enabled, the [`tls.verify_https_client`][]
|
||||
configuration must be set to `false` since it is not possible to provide client
|
||||
certificates to the Consul auth method.
|
||||
|
||||
Alternatively, you may expose Nomad's JWKS URL from a proxy or a load balancer
|
||||
that handles the mutual TLS connection to Nomad and exposes the JWKS URL
|
||||
endpoint over standard TLS.
|
||||
|
||||
#### Consul Servers Not Able to Connect to Nomad
|
||||
|
||||
If the Consul servers are not able to reach Nomad's JWKS URL, you may read the
|
||||
public keys from Nomad's [`/.well-known/jwks.json`][nomad_jwks_url] endpoint
|
||||
and provide them to the auth method directly using the
|
||||
[`JWTValidationPubKeys`][] parameter. The keys must be converted from JWKS to
|
||||
PEM format.
|
||||
|
||||
You may also host the JWKS JSON response from Nomad in an external location
|
||||
that is reachable by the Consul servers, and use that address as the value for
|
||||
`JWKSURL`.
|
||||
|
||||
It is important to remember that the Nomad keys **are rotated periodically**,
|
||||
so both approaches should be automated and done continually. The rotation
|
||||
frequency is controlled by the [`server.root_key_rotation_threshold`][]
|
||||
configuration of the Nomad servers.
|
||||
|
||||
### Additional References
|
||||
|
||||
The [Consul ACL with Nomad Workload Identities][consul_tutorial_wid] tutorial
|
||||
provides guided instructions on how to configure Consul and Nomad for workload
|
||||
identities.
|
||||
|
||||
The [`nomad setup consul`][nomad_cli_setup_consul] command and the
|
||||
[`hashicorp-modules/nomad-setup/consul`][tf_nomad_setup_consul] Terraform
|
||||
module can help you automate the process of applying configuration to a Consul
|
||||
cluster.
|
||||
|
||||
## Authenticating Without Workload Identity (Legacy)
|
||||
|
||||
If [Consul ACLs][consul_acls] are enabled, the [`allow_unauthenticated`][]
|
||||
configuration parameter will control whether a Consul token will be required
|
||||
when submitting a job with Consul namespace configured. The provided Consul
|
||||
token must belong to the correct namespace, and must be backed by a Consul ACL
|
||||
Policy with sufficient `service:write` and `kv:read` permissions. An example
|
||||
policy might look like the following.
|
||||
|
||||
```hcl
|
||||
key_prefix "" {
|
||||
policy = "read"
|
||||
}
|
||||
|
||||
service_prefix "" {
|
||||
policy = "write"
|
||||
}
|
||||
```
|
||||
|
||||
<Note title="Deprecation Warning">
|
||||
|
||||
This legacy workflow will be removed in Nomad 1.9. Before upgrading to Nomad 1.9
|
||||
you will need to have configured authentication with Consul as described in
|
||||
[Nomad Workload Identities](#nomad-workload-identities).
|
||||
|
||||
</Note>
|
||||
|
||||
## Migrating to Using Workload Identity with Consul
|
||||
|
||||
Migrating from the legacy (pre-1.7) workflow where workload use the agent's
|
||||
Consul token requires configuation on your Consul cluster and your Nomad server
|
||||
agents. It does not require updating your running Nomad jobs. To migrate:
|
||||
|
||||
* Create the Consul auth method and binding rules on your Consul cluster.
|
||||
* Enable [`consul.service_identity`][] blocks in your Nomad server agent configurations.
|
||||
* Enable [`consul.task_identity`][] blocks in your Nomad server agent configurations.
|
||||
* (Optionally) add [`identity`][] blocks to your jobs if you want to use a
|
||||
different identity because of how your auth method and binding rules are
|
||||
configured.
|
||||
|
||||
Note that when using Workload Identity you will no longer need to pass in a
|
||||
Consul token to submit a job.
|
||||
|
||||
[Variables]: /nomad/docs/concepts/variables
|
||||
[`-bind-name`]: /consul/commands/acl/binding-rule/create#bind-name
|
||||
[`-selector`]: /consul/commands/acl/binding-rule/create#selector
|
||||
[`BindNamespace`]: /consul/api-docs/acl/auth-methods#bindnamespace
|
||||
[`JWTValidationPubKeys`]: /consul/docs/security/acl/auth-methods/jwt#jwtvalidationpubkeys
|
||||
[`NamespaceRules`]: /consul/api-docs/acl/auth-methods#namespacerules
|
||||
[`Selector`]: /consul/api-docs/acl/auth-methods#selector
|
||||
[`allow_unauthenticated`]: /nomad/docs/configuration/consul#allow_unauthenticated
|
||||
[`aud`]: /nomad/docs/job-specification/identity#aud
|
||||
[`consul.namespace`]: /nomad/docs/job-specification/consul#namespace
|
||||
[`consul.service_auth_method`]: /nomad/docs/configuration/consul#service_auth_method
|
||||
[`consul.service_identity`]: /nomad/docs/configuration/consul#service_identity
|
||||
[`consul.task_auth_method`]: /nomad/docs/configuration/consul#task_auth_method
|
||||
[`consul.task_identity`]: /nomad/docs/configuration/consul#task_identity
|
||||
[`consul`]: /nomad/docs/job-specification/consul
|
||||
[`identity`]: /nomad/docs/job-specification/identity
|
||||
[`server.root_key_rotation_threshold`]: /nomad/docs/configuration/server#root_key_rotation_threshold
|
||||
[`template`]: /nomad/docs/job-specification/template
|
||||
[`tls.verify_https_client`]: /nomad/docs/configuration/tls#verify_https_client
|
||||
[consul_acl_policy]: /consul/docs/security/acl/acl-policies
|
||||
[consul_acl_role]: /consul/docs/security/acl/acl-roles
|
||||
[consul_acls]: /consul/docs/security/acl
|
||||
[consul_auth_methods]: /consul/docs/security/acl/auth-methods
|
||||
[consul_binding_rules]: /consul/api-docs/acl/binding-rules
|
||||
[consul_config_entry]: /consul/docs/connect/config-entries
|
||||
[consul_jwt_auth_method]: /consul/docs/security/acl/auth-methods/jwt
|
||||
[consul_si]: /consul/docs/security/acl/acl-roles#service-identities
|
||||
[consul_tutorial_wid]: /nomad/tutorials/integrate-consul/consul-acl
|
||||
[img_consul_auth]: /img/consul-integration-wi.png
|
||||
[img_consul_auth_method]: /img/consul-integration-auth-method.png
|
||||
[img_consul_wid_acl_token]: /img/consul-integration-wid-acl-token.png
|
||||
[int_consul_ns]: /nomad/docs/integrations/consul#consul-namespaces
|
||||
[jobspec_identity_consul]: /nomad/docs/job-specification/identity#workload-identities-for-consul
|
||||
[jwt]: https://jwt.io/
|
||||
[nomad_cli_setup_consul]: /nomad/docs/commands/setup/consul
|
||||
[nomad_jwks_url]: /nomad/api-docs/operator/keyring#list-active-public-keys
|
||||
[nomad_wid]: /nomad/docs/concepts/workload-identity
|
||||
[nomad_wid_claims]: /nomad/docs/concepts/workload-identity#workload-identity-claims
|
||||
[tf_nomad_setup_consul]: https://registry.terraform.io/modules/hashicorp-modules/nomad-setup/consul/
|
||||
[tutorial_mtls]: /nomad/tutorials/transport-security/security-enable-tls
|
||||
186
website/content/docs/integrations/consul/index.mdx
Normal file
186
website/content/docs/integrations/consul/index.mdx
Normal file
@@ -0,0 +1,186 @@
|
||||
---
|
||||
layout: docs
|
||||
page_title: Consul Integration
|
||||
description: Learn how to integrate Nomad with Consul and add service discovery to jobs
|
||||
---
|
||||
|
||||
# Consul Integration
|
||||
|
||||
[Consul][] is a tool for discovering and configuring services in your
|
||||
infrastructure. Consul's key features include service discovery, health checking,
|
||||
a KV store, and robust support for multi-datacenter deployments. Nomad's integration
|
||||
with Consul enables automatic clustering, built-in service registration, and
|
||||
dynamic rendering of configuration files and environment variables. The sections
|
||||
below describe the integration in more detail.
|
||||
|
||||
## Configuration
|
||||
|
||||
In order to use Consul with Nomad, you will need to configure and install Consul
|
||||
on your nodes alongside Nomad, or schedule it as a system job. Nomad does not
|
||||
run Consul for you.
|
||||
|
||||
To enable Consul integration, please refer to the [Nomad agent Consul
|
||||
configuration][] documentation.
|
||||
|
||||
## Automatic Clustering with Consul
|
||||
|
||||
Nomad servers and clients will be automatically informed of each other's
|
||||
existence when a running Consul cluster already exists and the Consul agent is
|
||||
installed and configured on each host. Please refer to the [Automatic Clustering
|
||||
with Consul][] guide for more information.
|
||||
|
||||
## Service Discovery
|
||||
|
||||
Nomad schedules workloads of various types across a cluster of generic hosts.
|
||||
Because of this, placement is not known in advance and you will need to use
|
||||
service discovery to connect tasks to other services deployed across your
|
||||
cluster. Nomad integrates with Consul to provide service discovery and
|
||||
monitoring.
|
||||
|
||||
To configure a job to register with service discovery, please refer to the
|
||||
[`service` job specification documentation][service].
|
||||
|
||||
## Service Mesh
|
||||
|
||||
Consul service mesh provides service-to-service connection authorization and
|
||||
encryption using mutual Transport Layer Security (TLS). Nomad can automatically
|
||||
provision the components necessary to securely connect your tasks to Consul's
|
||||
service mesh.
|
||||
|
||||
Refer to the [Consul Service Mesh integration page][int_consul_mesh] for more
|
||||
information.
|
||||
|
||||
## Dynamic Configuration
|
||||
|
||||
Nomad's job specification includes a [`template`][] block that uses a Consul
|
||||
ecosystem tool called [Consul Template][]. This mechanism creates a convenient
|
||||
way to ship configuration files that are populated from environment variables,
|
||||
Consul data, Vault secrets, or just general configurations within a Nomad task.
|
||||
|
||||
For more information on Nomad's template block and how it leverages Consul
|
||||
Template, please see the [`template` job specification documentation][].
|
||||
|
||||
## Consul ACL
|
||||
|
||||
The Consul ACL system protects the cluster from unauthorized access. When
|
||||
enabled, both Consul and Nomad must be properly configured in order for their
|
||||
integrations to work.
|
||||
|
||||
Refer to the [Consul ACL integration page][int_consul_acl] for more
|
||||
information.
|
||||
|
||||
## Consul Namespaces <EnterpriseAlert inline/>
|
||||
|
||||
Nomad provides integration with [Consul Namespaces][consul_namespaces] for
|
||||
service registrations specified in `service` blocks and Consul KV reads in
|
||||
`template` blocks.
|
||||
|
||||
By default, Nomad will not specify a Consul namespace on service registrations
|
||||
or KV store reads, which Consul then implicitly resolves to the `"default"`
|
||||
namespace. This default namespace behavior can be modified by setting the
|
||||
[`namespace`][consul_agent_namespace] field in the Nomad agent Consul
|
||||
configuration block.
|
||||
|
||||
For more control over Consul namespaces, Nomad Enterprise supports configuring
|
||||
the Consul [namespace][consul_jobspec_namespace] at the group or task level in
|
||||
the Nomad job spec as well as the [`-consul-namespace`][consul_run_namespace]
|
||||
command line argument for `job run`.
|
||||
|
||||
The Consul namespace used for a set of group or task service registrations
|
||||
within a group, as well as `template` KV store access is determined from the
|
||||
following hierarchy from highest to lowest precedence:
|
||||
|
||||
* group and task configuration: Consul
|
||||
[namespace field][consul_jobspec_namespace] defined in the job at the task or
|
||||
group level.
|
||||
|
||||
* job run command option: Consul namespace defined in the
|
||||
[`-consul-namespace`][consul_run_namespace] command line option on job
|
||||
submission.
|
||||
|
||||
* job run command environment various: Consul namespace defined as the
|
||||
[`CONSUL_NAMESPACE`][consul_env_namespace] environment variable on job
|
||||
submission.
|
||||
|
||||
* agent configuration: Consul namespace defined in the
|
||||
[`namespace`][consul_agent_namespace] Nomad agent Consul configuration
|
||||
parameter.
|
||||
|
||||
* Consul default: If no Consul namespace options are configured, Consul will
|
||||
automatically make use of the `"default"` namespace.
|
||||
|
||||
## Multiple Consul Clusters <EnterpriseAlert inline />
|
||||
|
||||
Nomad Enterprise supports access to multiple Consul clusters. They can be
|
||||
configured using multiple [`consul`][nomad_config_consul] blocks with different
|
||||
`name` values. If a `name` is not provided, the cluster configuration is called
|
||||
`default`. Nomad automatic clustering uses the `default` cluster for service
|
||||
discovery.
|
||||
|
||||
Jobs that need access to Consul may specify which Consul cluster to use with
|
||||
the [`consul.cluster`][] parameter.
|
||||
|
||||
## Assumptions
|
||||
|
||||
* Each Nomad client should have a local Consul agent running on the same host,
|
||||
reachable by Nomad. Nomad clients should never share a Consul agent or talk
|
||||
directly to the Consul servers. Nomad is not compatible with [Consul Data
|
||||
Plane][CDP].
|
||||
|
||||
* The service discovery feature in Nomad depends on operators making sure that
|
||||
the Nomad client can reach the Consul agent.
|
||||
|
||||
* Tasks running inside Nomad also need to reach out to the Consul agent if
|
||||
they want to use any of the Consul APIs. Ex: A task running inside a docker
|
||||
container in the bridge mode won't be able to talk to a Consul Agent running
|
||||
on the loopback interface of the host since the container in the bridge mode
|
||||
has its own network interface and doesn't see interfaces on the global
|
||||
network namespace of the host. There are a couple of ways to solve this, one
|
||||
way is to run the container in the host networking mode, or make the Consul
|
||||
agent listen on an interface in the network namespace of the container.
|
||||
|
||||
* The `consul` binary must be present in Nomad's `$PATH` to run the Envoy
|
||||
proxy sidecar on client nodes.
|
||||
|
||||
* Consul service mesh using network namespaces is only supported on Linux.
|
||||
|
||||
## Compatibility
|
||||
|
||||
Most supported versions of Nomad are compatible with most recent versions of
|
||||
Consul, with some exceptions.
|
||||
|
||||
* Nomad versions 1.6.0+, 1.5.6+, and 1.4.11+ are compatible with any currently
|
||||
supported version of Consul.
|
||||
* Nomad versions 1.4.4 to 1.4.11 and 1.5.0 to 1.5.6 are compatible with any
|
||||
currently supported version of Consul except 1.13.8.
|
||||
* Nomad versions 1.4.0 through 1.4.3 are compatible with Consul versions 1.13.0
|
||||
through 1.13.7, and 1.13.9. Changes to Consul service mesh in version 1.14 are
|
||||
incompatible with Nomad 1.4.3 and earlier.
|
||||
* Nomad is not compatible with Consul Data Plane.
|
||||
|
||||
| | Consul 1.13.0 - 1.13.7 | Consul 1.13.8 | Consul 1.13.9 | Consul 1.14.0+ |
|
||||
|---------------------|------------------------|---------------|---------------|----------------|
|
||||
| Nomad 1.6.0+ | ✅ | ✅ | ✅ | ✅ |
|
||||
| Nomad 1.5.6+ | ✅ | ✅ | ✅ | ✅ |
|
||||
| Nomad 1.5.0-1.5.5 | ✅ | ❌ | ✅ | ✅ |
|
||||
| Nomad 1.4.11-1.4.13 | ✅ | ✅ | ✅ | ✅ |
|
||||
| Nomad 1.4.4-1.4.10 | ✅ | ❌ | ✅ | ✅ |
|
||||
| Nomad 1.4.0-1.4.3 | ✅ | ❌ | ✅ | ❌ |
|
||||
|
||||
[Automatic Clustering with Consul]: /nomad/tutorials/manage-clusters/clustering
|
||||
[CDP]: /consul/docs/connect/dataplane
|
||||
[Consul Template]: https://github.com/hashicorp/consul-template
|
||||
[Consul]: https://www.consul.io/ "Consul by HashiCorp"
|
||||
[Nomad agent Consul configuration]: /nomad/docs/configuration/consul
|
||||
[`consul.cluster`]: /nomad/docs/job-specification/consul#cluster
|
||||
[`template` job specification documentation]: /nomad/docs/job-specification/template#consul-integration
|
||||
[`template`]: /nomad/docs/job-specification/template
|
||||
[consul_agent_namespace]: /nomad/docs/configuration/consul#namespace
|
||||
[consul_jobspec_namespace]: /nomad/docs/job-specification/consul#namespace
|
||||
[consul_namespaces]: /consul/docs/enterprise/namespaces
|
||||
[consul_run_namespace]: /nomad/docs/commands/job/run#consul-namespace
|
||||
[consul_env_namespace]: /consul/commands#consul_namespace
|
||||
[int_consul_acl]: /nomad/docs/integrations/consul/acl
|
||||
[int_consul_mesh]: /nomad/docs/integrations/consul/service-mesh
|
||||
[nomad_config_consul]: /nomad/docs/configuration/consul
|
||||
[service]: /nomad/docs/job-specification/service "Nomad service Job Specification"
|
||||
@@ -1,137 +1,256 @@
|
||||
---
|
||||
layout: docs
|
||||
page_title: Vault Integration
|
||||
description: >-
|
||||
Learn how to integrate Nomad with HashiCorp Vault and retrieve Vault tokens
|
||||
for tasks.
|
||||
page_title: Vault ACL
|
||||
description: Learn how to integrate Nomad with Vault when ACL is enabled.
|
||||
---
|
||||
|
||||
# Vault Integration
|
||||
# Vault ACL
|
||||
|
||||
Many workloads require access to tokens, passwords, certificates, API keys, and
|
||||
other secrets. To enable secure, auditable and easy access to your secrets,
|
||||
Nomad integrates with HashiCorp's [Vault][]. Nomad servers and clients
|
||||
coordinate with Vault to derive a Vault token that has access to only the Vault
|
||||
policies the tasks needs. Nomad clients make the token available to the task and
|
||||
handle the tokens renewal. Further, Nomad's [`template` block][template] can
|
||||
retrieve secrets from Vault making it easier than ever to secure your
|
||||
infrastructure.
|
||||
The Vault ACL system protects the cluster from unauthorized access. It must be
|
||||
properly configured in order for the Vault and Nomad integrations to work.
|
||||
|
||||
Note that in order to use Vault with Nomad, you will need to configure and
|
||||
install Vault separately from Nomad. Nomad does not run Vault for you.
|
||||
## Nomad Workload Identities
|
||||
|
||||
## Agent Configuration
|
||||
Starting in Nomad 1.7, Nomad clients can use a task's [Workload Identity][] to
|
||||
authenticate to Vault and obtain a Vault ACL token specific to the task. When
|
||||
using Nomad workload identities, you no longer need to pass in a Vault ACL
|
||||
token to submit a job.
|
||||
|
||||
To enable Vault integration, please see the [Nomad agent Vault
|
||||
integration][config] configuration.
|
||||
By default, Nomad only generates a workload identity for tasks that can be used
|
||||
to access Nomad itself, such as for reading [Variables][] from a [`template`][]
|
||||
block. To access Vault, jobs must have additional workload identities defined
|
||||
as [`identity`][] blocks.
|
||||
|
||||
## Vault Definition Syntax
|
||||
To avoid having to add these additional identities to every job, you can
|
||||
configure the Nomad servers with the [`vault.default_identity`][] agent
|
||||
configuration. Upon job registration, the Nomad servers update tasks that have
|
||||
a [`vault`][] block with this default identity.
|
||||
|
||||
To configure a job to retrieve Vault tokens, please see the [`vault` job
|
||||
specification documentation][vault-spec].
|
||||
|
||||
## Using Nomad Workload Identity with Vault
|
||||
|
||||
Starting in Nomad 1.7, Nomad clients will use a task's [Workload Identity][] to
|
||||
authenticate to Vault and obtain a Vault token specific to the task.
|
||||
You can also specify identities for Vault directly in the job. When provided,
|
||||
they override the Nomad server configuration. Refer to the [Workload Identities
|
||||
for Vault][jobspec_identity_vault] section of the `identity` block
|
||||
documentation for more information.
|
||||
|
||||
### Configuring Vault Authentication
|
||||
|
||||
To configure Vault for use with Nomad workload identity, you'll need to enable the Vault
|
||||
JWT backend, create a Vault role and auth method, and finally create Vault
|
||||
policies to that map Nomad workload claims to secrets in Vault.
|
||||
Vault must be configured to receive, validate, and trust these Nomad workload
|
||||
identities. Since they are encoded as [JSON Web Tokens (JWTs)][jwt], you must
|
||||
create a [JWT ACL auth method][vault_jwt_auth_method]. The auth method is an
|
||||
endpoint that Nomad can use to exchange workload identities for Vault ACL
|
||||
tokens.
|
||||
|
||||
<EnterpriseAlert>
|
||||
Refer to Vault's [Authentication][vault_auth] documentation for more
|
||||
information.
|
||||
|
||||
Nomad Enterprise users who are using Vault Namespaces should
|
||||
note that you will need to pass the `-namespace` flag for each of the commands
|
||||
below. Each Vault namespace needs its own auth method, role, and
|
||||
policies.
|
||||
#### Vault Auth Method
|
||||
|
||||
</EnterpriseAlert>
|
||||
The auth method configuration points to Nomad's [JSON Web Key Set (JWKS)
|
||||
URL][nomad_jwks_url]. Vault servers call this URL to retrieve the public keys
|
||||
Nomad uses to sign workload identities. With these keys, Vault is able to
|
||||
validate their origin and confirm that they were actually created by Nomad.
|
||||
|
||||
First enable the JWT authentication backend.
|
||||
|
||||
```shell-session
|
||||
$ vault auth enable jwt
|
||||
```
|
||||
|
||||
Create a configuration file for the default Vault [Role][]. This configuration
|
||||
maps each Nomad job to its own Vault user claim. You can set the `token_period`
|
||||
and `token_policies` to whatever value is suitable for your environment. A
|
||||
recommended policy is shown later.
|
||||
|
||||
```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"
|
||||
},
|
||||
"token_period": "30m",
|
||||
"token_type": "service",
|
||||
"token_policies": ["nomad-workloads"]
|
||||
}
|
||||
```
|
||||
|
||||
Using that configuration file, create the Vault role.
|
||||
|
||||
```shell-session
|
||||
$ vault write auth/jwt/role/nomad-workloads @vault-role.json
|
||||
```
|
||||
|
||||
Create a configuration file for a Vault [JWT Auth Method][]. The `jwks_url`
|
||||
field should point to all the Nomad servers; you should use a proxy or DNS A
|
||||
Record to ensure that requests can go to any server in the cluster. The
|
||||
`default_role` should match the name of the role you created above.
|
||||
<CodeBlockConfig highlight="2" filename="auth-method.json">
|
||||
|
||||
```json
|
||||
{
|
||||
"jwks_url": "https://nomad.example.com:4646/.well-known/jwks.json",
|
||||
"jwt_supported_algs": ["RS256"],
|
||||
"jwt_supported_algs": ["RS256", "EdDSA"],
|
||||
"default_role": "nomad-workloads"
|
||||
}
|
||||
```
|
||||
|
||||
Using that configuration file, create the Vault auth method.
|
||||
</CodeBlockConfig>
|
||||
|
||||
```shell-session
|
||||
$ vault write auth/jwt/config @vault-auth-method.json
|
||||
The `jwks_url` address must be reachable by all Vault servers and should
|
||||
resolve to multiple Nomad agents to avoid a single point of failure. Both Nomad
|
||||
servers and clients are able to handle this request.
|
||||
|
||||
Refer to the [Important Considerations About the JWKS
|
||||
URL](#important-considerations-about-the-jwks-url) section for additional
|
||||
information on how to configure the `jwks_url` value.
|
||||
|
||||
[![Vault Auth Method][img_vault_auth_method]][img_vault_auth_method]
|
||||
|
||||
When an allocation that needs access access to Vault starts, the Nomad client
|
||||
running it exchanges the Nomad workload identities for tasks for Vault ACL
|
||||
tokens.
|
||||
|
||||
[![Vault JWT Login][img_vault_wid_acl_token]][img_vault_wid_acl_token]
|
||||
|
||||
#### Vault ACL Role
|
||||
|
||||
A Vault [ACL role][vault_role] groups multiple ACL policies to apply to a token
|
||||
and determine the permissions it receives.
|
||||
|
||||
The auth method may define a default ACL role that is applied to the ACL tokens
|
||||
it generates. If no default role is set, the role must be provided in the job
|
||||
using the [`vault.role`][] parameter or in the Nomad client configuration
|
||||
[`vault.create_from_role`][].
|
||||
|
||||
<CodeBlockConfig highlight="4" filename="auth-method.json">
|
||||
|
||||
```json
|
||||
{
|
||||
"jwks_url": "https://nomad.example.com:4646/.well-known/jwks.json",
|
||||
"jwt_supported_algs": ["RS256", "EdDSA"],
|
||||
"default_role": "nomad-workloads"
|
||||
}
|
||||
```
|
||||
|
||||
Next you'll write Vault policies for the role. A recommended approach is to use
|
||||
the mapping of Nomad workload claims to Vault entities you configured above to
|
||||
grant access to paths that match the claims. For example, for a Nomad job "web"
|
||||
in namespace "prod", you can grant the job automatic access to secrets at the
|
||||
Vault path `secret/data/prod/web`.
|
||||
</CodeBlockConfig>
|
||||
|
||||
To write a policy like this, first you'll need the unique Accessor of the JWT auth
|
||||
backend you created earlier.
|
||||
The ACL role specifies the list of authorized audience values using the
|
||||
[`bound_audiences`][], which must have at least one match with the values
|
||||
defined in the Nomad workload identity [`aud`][] parameter. For security
|
||||
reasons, it is recommended to only define a single audience value.
|
||||
|
||||
```shell-session
|
||||
$ vault auth list
|
||||
Path Type Accessor Description Version
|
||||
---- ---- -------- ----------- -------
|
||||
jwt/ jwt auth_jwt_3a9350fe n/a n/a
|
||||
<CodeBlockConfig highlight="3" filename="acl-role.json">
|
||||
|
||||
```json
|
||||
{
|
||||
"role_type": "jwt",
|
||||
"bound_audiences": ["vault.io"],
|
||||
"bound_claims": {
|
||||
"nomad_namespace": "default",
|
||||
"nomad_job_id": "mongo"
|
||||
},
|
||||
"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
|
||||
}
|
||||
```
|
||||
|
||||
Next, write a Vault policy file using that accessor. Note that `auth_jwt_3a9350fe` here
|
||||
is the accessor shown above and you should replace it with
|
||||
the results from your own Vault cluster.
|
||||
</CodeBlockConfig>
|
||||
|
||||
Nomad workload identities have a set of [claims][nomad_wid_claims] that can be
|
||||
referenced in Vault ACL configuration. The ACL role uses the
|
||||
[`claim_mappings`][] parameter to determine which of these claims are made
|
||||
available to the rest of the configuration.
|
||||
|
||||
The [`bound_claims`][] parameter restricts which workload identities are able
|
||||
to use the role based on their claims. Refer to Vault's [Bound
|
||||
Claims][vault_bound_claims] documentation for more information.
|
||||
|
||||
<CodeBlockConfig highlight="4-7,10-14" filename="acl-role.json">
|
||||
|
||||
```json
|
||||
{
|
||||
"role_type": "jwt",
|
||||
"bound_audiences": ["vault.io"],
|
||||
"bound_claims": {
|
||||
"nomad_namespace": "default",
|
||||
"nomad_job_id": "mongo"
|
||||
},
|
||||
"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>
|
||||
|
||||
Vault has different [types of ACL tokens][vault_token_types]. Nomad uses tokens
|
||||
of type `service` since they can be renewed for as long as the workload is
|
||||
active. Nomad automatically renews the Vault ACL tokens it generates before
|
||||
they expire. To ensure the tokens can be renewed for as long as necessary,
|
||||
[`token_explicit_max_ttl`][] must be set to 0.
|
||||
|
||||
<CodeBlockConfig highlight="16-18" filename="acl-role.json">
|
||||
|
||||
```json
|
||||
{
|
||||
"role_type": "jwt",
|
||||
"bound_audiences": ["vault.io"],
|
||||
"bound_claims": {
|
||||
"nomad_namespace": "default",
|
||||
"nomad_job_id": "mongo"
|
||||
},
|
||||
"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_policies": ["nomad-workloads"],
|
||||
"token_type": "service",
|
||||
"token_period": "30m",
|
||||
"token_explicit_max_ttl": 0
|
||||
}
|
||||
```
|
||||
|
||||
</CodeBlockConfig>
|
||||
|
||||
#### Vault ACL Policy
|
||||
|
||||
A Vault ACL role may have one or more ACL policies attached. Vault [ACL
|
||||
policies][vault_policies] define the permissions granted to an ACL
|
||||
token.
|
||||
|
||||
<CodeBlockConfig highlight="15" filename="acl-role.json">
|
||||
|
||||
```json
|
||||
{
|
||||
"role_type": "jwt",
|
||||
"bound_audiences": ["vault.io"],
|
||||
"bound_claims": {
|
||||
"nomad_namespace": "default",
|
||||
"nomad_job_id": "mongo"
|
||||
},
|
||||
"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_policies": ["nomad-workloads"],
|
||||
"token_type": "service",
|
||||
"token_period": "30m",
|
||||
"token_explicit_max_ttl": 0
|
||||
}
|
||||
```
|
||||
|
||||
</CodeBlockConfig>
|
||||
|
||||
ACL policies can reference dynamic values from Nomad workload identities claims
|
||||
exposed from the ACL role in [templated policies][vault_templated_policies].
|
||||
The exact ACL policy rules will depend on the level of access required by
|
||||
tasks.
|
||||
|
||||
The following example ACL policy automatically grants `read` permissions to
|
||||
secrets in the path `secret/data/<job namespace>/<job name>/*`, where `<job
|
||||
namespace>` and `<job name>` are read from the workload identity claims
|
||||
`nomad_namespace` and `nomad_job_id`.
|
||||
|
||||
<CodeBlockConfig highlight="1,5,9" filename="acl-policy.hcl">
|
||||
|
||||
```hcl
|
||||
path "secret/data/{{identity.entity.aliases.auth_jwt_3a9350fe.metadata.nomad_namespace}}/{{identity.entity.aliases.auth_jwt_3a9350fe.metadata.nomad_job_id}}/*" {
|
||||
path "secret/data/{{identity.entity.aliases.auth_jwt_d34481ad.metadata.nomad_namespace}}/{{identity.entity.aliases.auth_jwt_d34481ad.metadata.nomad_job_id}}/*" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
|
||||
path "secret/data/{{identity.entity.aliases.auth_jwt_3a9350fe.metadata.nomad_namespace}}/{{identity.entity.aliases.auth_jwt_3a9350fe.metadata.nomad_job_id}}" {
|
||||
path "secret/data/{{identity.entity.aliases.auth_jwt_d34481ad.metadata.nomad_namespace}}/{{identity.entity.aliases.auth_jwt_d34481ad.metadata.nomad_job_id}}" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
|
||||
path "secret/metadata/{{identity.entity.aliases.auth_jwt_3a9350fe.metadata.nomad_namespace}}/*" {
|
||||
path "secret/metadata/{{identity.entity.aliases.auth_jwt_d34481ad.metadata.nomad_namespace}}/*" {
|
||||
capabilities = ["list"]
|
||||
}
|
||||
|
||||
@@ -140,14 +259,66 @@ path "secret/metadata/*" {
|
||||
}
|
||||
```
|
||||
|
||||
Using that policy configuration file, create the Vault policy.
|
||||
</CodeBlockConfig>
|
||||
|
||||
```shell-session
|
||||
$ vault policy write nomad-workloads vault-policy.hcl
|
||||
```
|
||||
The overall configuration structure is illustrated in the following diagram.
|
||||
|
||||
You can write additional Vault policies that give Nomad workloads using the
|
||||
default role access to other secrets.
|
||||
[![Vault Auth Overview][img_vault_auth_overview]][img_vault_auth_overview]
|
||||
|
||||
#### Vault Namespaces <EnterpriseAlert inline />
|
||||
|
||||
Vault Enterprise supports multiple namespaces and jobs in Nomad Enterprise can
|
||||
use the [`vault.namespace`][] parameter to specify which namespace to use. In a
|
||||
multi-namespace environment, the authentication setup described must be applied
|
||||
to each Vault namespace used by jobs.
|
||||
|
||||
### Important Considerations About the JWKS URL
|
||||
|
||||
The recommended configuration assumes Vault servers are able to connect to
|
||||
Nomad agents (either client or servers) to retrieve the JSON Web Key Set
|
||||
information.
|
||||
|
||||
This section covers additional aspects you should consider depending on how
|
||||
your Vault and Nomad clusters are configured and deployed.
|
||||
|
||||
#### Mutual TLS in Nomad
|
||||
|
||||
It is highly recommended to use [mutual TLS][tutorial_mtls] in production
|
||||
deployments of Nomad. With mTLS enabled, the [`tls.verify_https_client`][]
|
||||
configuration must be set to `false` since it is not possible to provide client
|
||||
certificates to the Vault auth method.
|
||||
|
||||
Alternatively, you may expose Nomad's JWKS URL from a proxy or a load balancer
|
||||
that handles the mutual TLS connection to Nomad and exposes the JWKS URL
|
||||
endpoint over standard TLS.
|
||||
|
||||
#### Vault Servers Not Able to Connect to Nomad
|
||||
|
||||
If the Vault servers are not able to reach Nomad's JWKS URL, you may read the
|
||||
public keys from Nomad's [`/.well-known/jwks.json`][nomad_jwks_url] endpoint
|
||||
and provide them to the auth method directly using the
|
||||
[`jwt_validation_pubkeys`][] parameter. The keys must be converted from JWKS to
|
||||
PEM format.
|
||||
|
||||
You may also host the JWKS JSON response from Nomad in an external location
|
||||
that is reachable by the Vault servers, and use that address as the value for
|
||||
`jwks_url`.
|
||||
|
||||
It is important to remember that the Nomad keys **are rotated periodically**,
|
||||
so both approaches should be automated and done continually. The rotation
|
||||
frequency is controlled by the [`server.root_key_rotation_threshold`][]
|
||||
configuration of the Nomad servers.
|
||||
|
||||
### Additional References
|
||||
|
||||
The [Vault ACL with Nomad Workload Identities][vault_tutorial_wid] tutorial
|
||||
provides guided instructions on how to configure Vault and Nomad for workload
|
||||
identities.
|
||||
|
||||
The [`nomad setup vault`][nomad_cli_setup_vault] command and the
|
||||
[`hashicorp-modules/nomad-setup/vault`][tf_nomad_setup_vault] Terraform
|
||||
module can help you automate the process of applying configuration to a Vault
|
||||
cluster.
|
||||
|
||||
## Authentication Without Workload Identity (Legacy)
|
||||
|
||||
@@ -158,11 +329,11 @@ get started, but we recommend a token role based token for production
|
||||
installations. Nomad servers will renew the token automatically. **Note that the
|
||||
Nomad clients do not need to be provided with a Vault token.**
|
||||
|
||||
<Note>
|
||||
<Note title="Deprecation Warning">
|
||||
|
||||
This legacy workflow will be removed in Nomad 1.9. Before upgrading to Nomad 1.9
|
||||
you will need to have configured authentication with Vault as described in
|
||||
[Configuring Vault Authentication](#configuring-vault-authentication).
|
||||
[Nomad Workload Identities](#nomad-workload-identities).
|
||||
|
||||
</Note>
|
||||
|
||||
@@ -246,12 +417,12 @@ path "auth/token/renew-self" {
|
||||
}
|
||||
```
|
||||
|
||||
The above [`nomad-server` policy](https://developer.hashicorp.com/nomad/data/vault/nomad-server-policy.hcl) is
|
||||
The above [`nomad-server` policy](https://nomadproject.io/data/vault/nomad-server-policy.hcl) is
|
||||
available for download. Below is an example of writing this policy to Vault:
|
||||
|
||||
```shell-session
|
||||
# Download the policy
|
||||
$ curl https://developer.hashicorp.com/nomad/data/vault/nomad-server-policy.hcl -O -s -L
|
||||
$ curl https://nomadproject.io/data/vault/nomad-server-policy.hcl -O -s -L
|
||||
|
||||
# Write the policy to Vault
|
||||
$ vault policy write nomad-server nomad-server-policy.hcl
|
||||
@@ -340,12 +511,12 @@ documentation for all possible fields and more complete documentation.
|
||||
- `renewable` - Specifies whether created tokens are renewable. **Must be set to
|
||||
`true`**. This allows Nomad to renew tokens for tasks.
|
||||
|
||||
The above [`nomad-cluster` token role](https://developer.hashicorp.com/nomad/data/vault/nomad-cluster-role.json) is
|
||||
The above [`nomad-cluster` token role](https://nomadproject.io/data/vault/nomad-cluster-role.json) is
|
||||
available for download. Below is an example of writing this role to Vault:
|
||||
|
||||
```shell-session
|
||||
# Download the token role
|
||||
$ curl https://developer.hashicorp.com/nomad/data/vault/nomad-cluster-role.json -O -s -L
|
||||
$ curl https://nomadproject.io/data/vault/nomad-cluster-role.json -O -s -L
|
||||
|
||||
# Create the token role with Vault
|
||||
$ vault write /auth/token/roles/nomad-cluster @nomad-cluster-role.json
|
||||
@@ -354,8 +525,8 @@ $ vault write /auth/token/roles/nomad-cluster @nomad-cluster-role.json
|
||||
#### Example Configuration
|
||||
|
||||
To make getting started easy, the basic [`nomad-server`
|
||||
policy](https://developer.hashicorp.com/nomad/data/vault/nomad-server-policy.hcl) and
|
||||
[`nomad-cluster` role](https://developer.hashicorp.com/nomad/data/vault/nomad-cluster-role.json) described above are
|
||||
policy](https://nomadproject.io/data/vault/nomad-server-policy.hcl) and
|
||||
[`nomad-cluster` role](https://nomadproject.io/data/vault/nomad-cluster-role.json) described above are
|
||||
available for download.
|
||||
|
||||
The below example assumes Vault is accessible, unsealed and the operator has
|
||||
@@ -363,8 +534,8 @@ appropriate permissions.
|
||||
|
||||
```shell-session
|
||||
# Download the policy and token role
|
||||
$ curl https://developer.hashicorp.com/nomad/data/vault/nomad-server-policy.hcl -O -s -L
|
||||
$ curl https://developer.hashicorp.com/nomad/data/vault/nomad-cluster-role.json -O -s -L
|
||||
$ curl https://nomadproject.io/data/vault/nomad-server-policy.hcl -O -s -L
|
||||
$ curl https://nomadproject.io/data/vault/nomad-cluster-role.json -O -s -L
|
||||
|
||||
# Write the policy to Vault
|
||||
$ vault policy write nomad-server nomad-server-policy.hcl
|
||||
@@ -593,31 +764,46 @@ specify a non-default role. To migrate:
|
||||
* (Optionally) add [`identity`][] blocks to your jobs if you want to use a
|
||||
different identity because of how your auth method and roles are configured.
|
||||
|
||||
## Compatibility
|
||||
|
||||
* Nomad versions 1.4.0 and above are compatible with any currently supported
|
||||
version of Vault.
|
||||
|
||||
| | Vault 1.13.0+ |
|
||||
|--------------|---------------|
|
||||
| Nomad 1.4.0+ | ✅ |
|
||||
|
||||
|
||||
[Vault]: https://www.vaultproject.io/ 'Vault by HashiCorp'
|
||||
[template]: /nomad/docs/job-specification/template 'Nomad template Job Specification'
|
||||
[config]: /nomad/docs/configuration/vault 'Nomad Vault Configuration Block'
|
||||
[vault-spec]: /nomad/docs/job-specification/vault 'Nomad Vault Job Specification'
|
||||
[Workload Identity]: /nomad/docs/concepts/workload-identity
|
||||
[Variables]: /nomad/docs/concepts/variables
|
||||
[Vault Namespaces]: /vault/docs/enterprise/namespaces
|
||||
[Role]: /vault/api-docs/auth/jwt#create-update-role
|
||||
[JWT Auth Method]: /vault/api-docs/auth/jwt#configure
|
||||
[auth]: /vault/docs/auth/token 'Vault Authentication Backend'
|
||||
[createfromrole]: /nomad/docs/configuration/vault#create_from_role 'Nomad vault create_from_role Configuration Flag'
|
||||
[tokenhierarchy]: /vault/docs/concepts/tokens#token-hierarchies-and-orphan-tokens 'Vault Tokens - Token Hierarchies and Orphan Tokens'
|
||||
[vault-secrets-version]: /vault/docs/secrets/kv 'KV Secrets Engine'
|
||||
[vault-kv-templates]: /nomad/docs/job-specification/template#vault-kv-api-v1 'Vault KV API v1'
|
||||
[ent]: /nomad/docs/integrations/vault-integration#enterprise-configuration
|
||||
[allow_unauth]: /nomad/docs/configuration/vault#allow_unauthenticated
|
||||
[`vault.default_identity`]: /nomad/docs/configuration/consul#default_identity
|
||||
[`vault.role`]: /nomad/docs/configuration/consul#role
|
||||
[Workload Identity]: /nomad/docs/concepts/workload-identity
|
||||
[`aud`]: /nomad/docs/job-specification/identity#aud
|
||||
[`bound_audiences`]: /vault/api-docs/auth/jwt#bound_audiences
|
||||
[`bound_claims`]: /vault/api-docs/auth/jwt#bound_claims
|
||||
[`claim_mappings`]: /vault/api-docs/auth/jwt#claim_mappings
|
||||
[`identity`]: /nomad/docs/job-specification/identity
|
||||
[`jwt_validation_pubkeys`]: /vault/api-docs/auth/jwt#jwt_validation_pubkeys
|
||||
[`server.root_key_rotation_threshold`]: /nomad/docs/configuration/server#root_key_rotation_threshold
|
||||
[`template`]: /nomad/docs/job-specification/template
|
||||
[`tls.verify_https_client`]: /nomad/docs/configuration/tls#verify_https_client
|
||||
[`token_explicit_max_ttl`]: /vault/api-docs/auth/jwt#token_explicit_max_ttl
|
||||
[`vault.create_from_role`]: /nomad/docs/configuration/vault#create_from_role
|
||||
[`vault.default_identity`]: /nomad/docs/configuration/vault#default_identity
|
||||
[`vault.namespace`]: /nomad/docs/job-specification/vault#namespace
|
||||
[`vault.role`]: /nomad/docs/job-specification/vault#role
|
||||
[`vault`]: /nomad/docs/job-specification/vault
|
||||
[allow_unauth]: /nomad/docs/configuration/vault#allow_unauthenticated
|
||||
[auth]: /vault/docs/auth/token 'Vault Authentication Backend'
|
||||
[config]: /nomad/docs/configuration/vault 'Nomad Vault Configuration Block'
|
||||
[ent]: #enterprise-configuration
|
||||
[img_vault_auth_method]: /img/vault-integration-auth-method.png
|
||||
[img_vault_auth_overview]: /img/vault-integration-auth-overview.png
|
||||
[img_vault_wid_acl_token]: /img/vault-integration-wid-acl-token.png
|
||||
[jobspec_identity_vault]: /nomad/docs/job-specification/identity#workload-identities-for-vault
|
||||
[jwt]: https://jwt.io/
|
||||
[nomad_cli_setup_vault]: /nomad/docs/commands/setup/vault
|
||||
[nomad_jwks_url]: /nomad/api-docs/operator/keyring#list-active-public-keys
|
||||
[nomad_wid_claims]: /nomad/docs/concepts/workload-identity#workload-identity-claims
|
||||
[tf_nomad_setup_vault]: https://registry.terraform.io/modules/hashicorp-modules/nomad-setup/vault
|
||||
[tokenhierarchy]: /vault/docs/concepts/tokens#token-hierarchies-and-orphan-tokens 'Vault Tokens - Token Hierarchies and Orphan Tokens'
|
||||
[tutorial_mtls]: /nomad/tutorials/transport-security/security-enable-tls
|
||||
[vault-kv-templates]: /nomad/docs/job-specification/template#vault-kv-api-v1 'Vault KV API v1'
|
||||
[vault-secrets-version]: /vault/docs/secrets/kv 'KV Secrets Engine'
|
||||
[vault_auth]: /vault/docs/concepts/auth
|
||||
[vault_bound_claims]: /vault/docs/auth/jwt#bound-claims
|
||||
[vault_jwt_auth_method]: /vault/api-docs/auth/jwt
|
||||
[vault_policies]: /vault/docs/concepts/policies
|
||||
[vault_role]: /vault/api-docs/auth/jwt#create-update-role
|
||||
[vault_templated_policies]: /vault/tutorials/policies/policy-templating
|
||||
[vault_token_types]: /vault/tutorials/tokens/tokens#token-types
|
||||
[vault_tutorial_wid]: /nomad/tutorials/integrate-vault/vault-acl
|
||||
71
website/content/docs/integrations/vault/index.mdx
Normal file
71
website/content/docs/integrations/vault/index.mdx
Normal file
@@ -0,0 +1,71 @@
|
||||
---
|
||||
layout: docs
|
||||
page_title: Vault Integration
|
||||
description: >-
|
||||
Learn how to integrate Nomad with HashiCorp Vault and retrieve Vault tokens
|
||||
for tasks.
|
||||
---
|
||||
|
||||
# Vault Integration
|
||||
|
||||
Many workloads require access to tokens, passwords, certificates, API keys, and
|
||||
other secrets. To enable secure, auditable and easy access to your secrets,
|
||||
Nomad integrates with HashiCorp's [Vault][]. Nomad servers and clients
|
||||
coordinate with Vault to derive a Vault token that has access to only the Vault
|
||||
policies the tasks needs. Nomad clients make the token available to the task and
|
||||
handle the tokens renewal.
|
||||
|
||||
## Configuration
|
||||
|
||||
In order to use Vault with Nomad, you will need to configure and install Vault
|
||||
separately from Nomad. Nomad does not run Vault for you.
|
||||
|
||||
## Agent Configuration
|
||||
|
||||
To enable Vault integration, Nomad agents must be configured with
|
||||
[`vault`][] blocks. Each block can be enabled or disabled and configures how
|
||||
Nomad connects to the Vault cluster.
|
||||
|
||||
## Dynamic Configuration with Secrets
|
||||
|
||||
Nomad's job specification includes a [`template`][] block that uses a tool
|
||||
called [Consul Template][]. When used with Vault, this mechanism creates a
|
||||
convenient way to ship configuration files that are populated from Vault
|
||||
secrets.
|
||||
|
||||
For more information on Nomad's template block please see the
|
||||
[`template` job specification documentation][].
|
||||
|
||||
## Vault ACL
|
||||
|
||||
The Vault ACL system protects the cluster from unauthorized access. When
|
||||
enabled, both Vault and Nomad must be properly configured in order for their
|
||||
integrations to work.
|
||||
|
||||
Refer to the [Vault ACL integration page][int_vault_acl] for more information.
|
||||
|
||||
## Multiple Vault Clusters <EnterpriseAlert inline />
|
||||
|
||||
Nomad Enterprise supports access to multiple Vault clusters. They can be
|
||||
configured using multiple [`vault`][] blocks with different `name` values. If a
|
||||
`name` is not provided, the cluster configuration is called `default`.
|
||||
|
||||
Jobs that need access to Vault may specify which Vault cluster to use with the
|
||||
[`vault.cluster`][] parameter.
|
||||
|
||||
## Compatibility
|
||||
|
||||
* Nomad versions 1.4.0 and above are compatible with any currently supported
|
||||
version of Vault.
|
||||
|
||||
| | Vault 1.13.0+ |
|
||||
|--------------|---------------|
|
||||
| Nomad 1.4.0+ | ✅ |
|
||||
|
||||
[Consul Template]: https://github.com/hashicorp/consul-template
|
||||
[Vault]: https://www.vaultproject.io/ 'Vault by HashiCorp'
|
||||
[`template` job specification documentation]: /nomad/docs/job-specification/template#vault-integration
|
||||
[`template`]: /nomad/docs/job-specification/template
|
||||
[`vault.cluster`]: /nomad/docs/job-specification/vault#cluster
|
||||
[`vault`]: /nomad/docs/configuration/vault 'Nomad Vault Configuration Block'
|
||||
[int_vault_acl]: /nomad/docs/integrations/vault/acl
|
||||
@@ -10,7 +10,9 @@ description: |-
|
||||
|
||||
<Placement
|
||||
groups={[
|
||||
['job', 'group', 'service', 'identity'],
|
||||
['job', 'group', 'task', 'identity'],
|
||||
['job', 'group', 'task', 'service', 'identity'],
|
||||
]}
|
||||
/>
|
||||
|
||||
@@ -89,7 +91,267 @@ job "docs" {
|
||||
It can be convenient to combine workload identity with Nomad's [Task API]
|
||||
[taskapi] for enabling tasks to access the Nomad API.
|
||||
|
||||
[taskuser]: /nomad/docs/job-specification/task#user "Nomad task Block"
|
||||
## Workload Identities for Consul
|
||||
|
||||
Jobs that need access to Consul can use Nomad workload identities for
|
||||
authentication. These identities are specified as additional `identity` blocks
|
||||
inside the task or service that will access Consul.
|
||||
|
||||
You can configure Nomad servers to automatically add default identities for
|
||||
Consul using the [`consul.service_identity`][] and [`consul.task_identity`][]
|
||||
agent configuration. Upon job registration, the Nomad server updates tasks that
|
||||
have a [`consul`][] or [`template`][] block and services that use the Consul
|
||||
service provider to include the default identities.
|
||||
|
||||
You can also specify these identities directly in the job. When provided, they
|
||||
override the default identities configured in the Nomad servers. Identities for
|
||||
tasks must have a [`name`](#name) that follows the pattern
|
||||
`consul_<cluster name>`. Identities for services do not need to specify a
|
||||
`name`.
|
||||
|
||||
In Nomad Community Edition, `<cluster_name>` is always `default`, so the task
|
||||
identity name should be `consul_default`.
|
||||
|
||||
<EnterpriseAlert>
|
||||
Nomad Enterprise supports multiple Consul clusters. The value of <code>
|
||||
<cluster_name></code> must be the same as the <a href="/nomad/docs/job-specification/consul#cluster">
|
||||
<code>consul.cluster</code></a> value for the task.
|
||||
</EnterpriseAlert>
|
||||
|
||||
Refer to [Nomad Workload Identities][int_consul_wid] section of the Consul
|
||||
integration documentation for more information.
|
||||
|
||||
<Tabs>
|
||||
<Tab heading="Nomad Community Edition" group="ce">
|
||||
<CodeBlockConfig highlight="3,14-17,30-34">
|
||||
|
||||
```hcl
|
||||
job "httpd" {
|
||||
group "httpd" {
|
||||
consul {}
|
||||
|
||||
network {
|
||||
port "http" {}
|
||||
}
|
||||
|
||||
service {
|
||||
provider = "consul"
|
||||
name = "httpd"
|
||||
port = "http"
|
||||
|
||||
identity {
|
||||
aud = ["consul.io"]
|
||||
ttl = "1h"
|
||||
}
|
||||
}
|
||||
|
||||
task "httpd" {
|
||||
driver = "docker"
|
||||
|
||||
config {
|
||||
image = "busybox:1.36"
|
||||
command = "httpd"
|
||||
args = ["-f", "-p", "${NOMAD_PORT_http}"]
|
||||
ports = ["http"]
|
||||
}
|
||||
|
||||
identity {
|
||||
name = "consul_default"
|
||||
aud = ["consul.io"]
|
||||
ttl = "1h"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</CodeBlockConfig>
|
||||
</Tab>
|
||||
<Tab heading="Nomad Enterprise" group="ent">
|
||||
<CodeBlockConfig highlight="3-5,16-19,34-38">
|
||||
|
||||
```hcl
|
||||
job "httpd" {
|
||||
group "httpd" {
|
||||
consul {
|
||||
cluster = "prod"
|
||||
}
|
||||
|
||||
network {
|
||||
port "http" {}
|
||||
}
|
||||
|
||||
service {
|
||||
provider = "consul"
|
||||
name = "httpd"
|
||||
port = "http"
|
||||
|
||||
identity {
|
||||
aud = ["consul.io"]
|
||||
ttl = "1h"
|
||||
}
|
||||
}
|
||||
|
||||
task "httpd" {
|
||||
driver = "docker"
|
||||
|
||||
config {
|
||||
image = "busybox:1.36"
|
||||
command = "httpd"
|
||||
args = ["-f", "-p", "${NOMAD_PORT_http}"]
|
||||
ports = ["http"]
|
||||
}
|
||||
|
||||
identity {
|
||||
name = "consul_prod"
|
||||
aud = ["consul.io"]
|
||||
ttl = "1h"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</CodeBlockConfig>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## Workload Identities for Vault
|
||||
|
||||
Jobs that need access to Vault can use Nomad workload identities for
|
||||
authentication. These identities are specified as additional `identity` blocks
|
||||
inside the task that will access Vault.
|
||||
|
||||
You can configure Nomad servers to automatically add default identities for
|
||||
Vault using the [`vault.default_identity`][] agent configuration. Upon job
|
||||
registration, the Nomad server updates tasks that have a [`vault`][] block to
|
||||
include the default identity.
|
||||
|
||||
You can also specify these identities directly in the job. When provided, they
|
||||
override the default identity configured in the Nomad servers. The identity
|
||||
[`name`](#name) must follow the pattern `vault_<cluster name>`.
|
||||
|
||||
In Nomad Community Edition, `<cluster_name>` is always `default`, so the
|
||||
identity name should be `vault_default`.
|
||||
|
||||
<EnterpriseAlert>
|
||||
Nomad Enterprise supports multiple Vault clusters. The value of <code>
|
||||
<cluster_name></code> must be the same as the <a href="/nomad/docs/job-specification/vault#cluster">
|
||||
<code>vault.cluster</code></a> value for the task.
|
||||
</EnterpriseAlert>
|
||||
|
||||
Refer to [Nomad Workload Identities][int_vault_wid] section of the Vault
|
||||
integration documentation for more information.
|
||||
|
||||
<Tabs>
|
||||
<Tab heading="Nomad Community Edition" group="ce">
|
||||
<CodeBlockConfig highlight="19,21-25">
|
||||
|
||||
```hcl
|
||||
job "mongo" {
|
||||
namespace = "default"
|
||||
|
||||
group "db" {
|
||||
network {
|
||||
port "db" {
|
||||
to = 27017
|
||||
}
|
||||
}
|
||||
|
||||
task "mongo" {
|
||||
driver = "docker"
|
||||
|
||||
config {
|
||||
image = "mongo:7"
|
||||
ports = ["db"]
|
||||
}
|
||||
|
||||
vault {}
|
||||
|
||||
identity {
|
||||
name = "vault_default"
|
||||
aud = ["vault.io"]
|
||||
ttl = "1h"
|
||||
}
|
||||
|
||||
template {
|
||||
data = <<EOF
|
||||
{{with secret "kv/data/default/mongo/config"}}
|
||||
MONGO_INITDB_ROOT_USERNAME=root
|
||||
MONGO_INITDB_ROOT_PASSWORD={{.Data.data.root_password}}
|
||||
{{end}}
|
||||
EOF
|
||||
destination = "secrets/env"
|
||||
env = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</CodeBlockConfig>
|
||||
</Tab>
|
||||
<Tab heading="Nomad Enterprise" group="ent">
|
||||
<CodeBlockConfig highlight="19-21,23-27">
|
||||
|
||||
```hcl
|
||||
job "mongo" {
|
||||
namespace = "default"
|
||||
|
||||
group "db" {
|
||||
network {
|
||||
port "db" {
|
||||
to = 27017
|
||||
}
|
||||
}
|
||||
|
||||
task "mongo" {
|
||||
driver = "docker"
|
||||
|
||||
config {
|
||||
image = "mongo:7"
|
||||
ports = ["db"]
|
||||
}
|
||||
|
||||
vault {
|
||||
cluster = "prod"
|
||||
}
|
||||
|
||||
identity {
|
||||
name = "vault_prod"
|
||||
aud = ["vault.io"]
|
||||
ttl = "1h"
|
||||
}
|
||||
|
||||
template {
|
||||
data = <<EOF
|
||||
{{with secret "kv/data/default/mongo/config"}}
|
||||
MONGO_INITDB_ROOT_USERNAME=root
|
||||
MONGO_INITDB_ROOT_PASSWORD={{.Data.data.root_password}}
|
||||
{{end}}
|
||||
EOF
|
||||
destination = "secrets/env"
|
||||
env = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</CodeBlockConfig>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
[Workload Identity]: /nomad/docs/concepts/workload-identity "Nomad Workload Identity"
|
||||
[windows]: https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/
|
||||
[`consul.cluster`]: /nomad/docs/job-specification/consul#cluster
|
||||
[`consul.service_identity`]: /nomad/docs/configuration/consul#service_identity
|
||||
[`consul.task_identity`]: /nomad/docs/configuration/consul#task_identity
|
||||
[`consul`]: /nomad/docs/job-specification/consul
|
||||
[`template`]: /nomad/docs/job-specification/template
|
||||
[`vault.default_identity`]: /nomad/docs/configuration/vault#default_identity
|
||||
[`vault`]: /nomad/docs/job-specification/vault
|
||||
[int_consul_wid]: /nomad/docs/integrations/consul-integration#nomad-workload-identities
|
||||
[int_vault_wid]: /nomad/docs/integrations/vault-integration#nomad-workload-identities
|
||||
[taskapi]: /nomad/api-docs/task-api
|
||||
[taskuser]: /nomad/docs/job-specification/task#user "Nomad task Block"
|
||||
[windows]: https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/
|
||||
|
||||
@@ -59,15 +59,33 @@
|
||||
},
|
||||
{
|
||||
"title": "Consul",
|
||||
"path": "integrations/consul-integration"
|
||||
"routes": [
|
||||
{
|
||||
"title": "Overview",
|
||||
"path": "integrations/consul"
|
||||
},
|
||||
{
|
||||
"title": "ACL",
|
||||
"path": "integrations/consul/acl"
|
||||
},
|
||||
{
|
||||
"title": "Service Mesh",
|
||||
"path": "integrations/consul/service-mesh"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"title": "Consul Service Mesh",
|
||||
"path": "integrations/consul-connect"
|
||||
},
|
||||
{
|
||||
"title": "Vault Integration",
|
||||
"path": "integrations/vault-integration"
|
||||
"title": "Vault",
|
||||
"routes": [
|
||||
{
|
||||
"title": "Overview",
|
||||
"path": "integrations/vault"
|
||||
},
|
||||
{
|
||||
"title": "ACL",
|
||||
"path": "integrations/vault/acl"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
BIN
website/public/img/consul-integration-auth-method.png
Normal file
BIN
website/public/img/consul-integration-auth-method.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 75 KiB |
BIN
website/public/img/consul-integration-wi.png
Normal file
BIN
website/public/img/consul-integration-wi.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 86 KiB |
BIN
website/public/img/consul-integration-wid-acl-token.png
Normal file
BIN
website/public/img/consul-integration-wid-acl-token.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 88 KiB |
BIN
website/public/img/vault-integration-auth-method.png
Normal file
BIN
website/public/img/vault-integration-auth-method.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 56 KiB |
BIN
website/public/img/vault-integration-auth-overview.png
Normal file
BIN
website/public/img/vault-integration-auth-overview.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 63 KiB |
BIN
website/public/img/vault-integration-wid-acl-token.png
Normal file
BIN
website/public/img/vault-integration-wid-acl-token.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 68 KiB |
@@ -45,4 +45,20 @@ module.exports = [
|
||||
destination: '/nomad/tools/autoscaling/concepts/policy-eval/node-selector-strategy',
|
||||
permanent: true,
|
||||
},
|
||||
// Redirect Consul and Vault integrations page
|
||||
{
|
||||
source: '/nomad/docs/integrations/vault-integration',
|
||||
destination: '/nomad/docs/integrations/vault',
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: '/nomad/docs/integrations/consul-integration',
|
||||
destination: '/nomad/docs/integrations/consul',
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: '/nomad/docs/integrations/consul-connect',
|
||||
destination: '/nomad/docs/integrations/consul/service-mesh',
|
||||
permanent: true,
|
||||
},
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user