diff --git a/website/content/docs/concepts/workload-identity.mdx b/website/content/docs/concepts/workload-identity.mdx index 07a5b17b6..347934105 100644 --- a/website/content/docs/concepts/workload-identity.mdx +++ b/website/content/docs/concepts/workload-identity.mdx @@ -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 + +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 diff --git a/website/content/docs/integrations/consul-integration.mdx b/website/content/docs/integrations/consul-integration.mdx deleted file mode 100644 index f3b5ee645..000000000 --- a/website/content/docs/integrations/consul-integration.mdx +++ /dev/null @@ -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. - - - -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. - - - -### 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. - - - - -```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" - } -} -``` - - - - -```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" - } -} -``` - - - - - - -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. - - - -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. - - - -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. - - - -#### 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. - - - - -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" -``` - - - - -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" -``` - - - - -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" -} -``` - - - -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). - - - -## 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: 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: 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 diff --git a/website/content/docs/integrations/consul/acl.mdx b/website/content/docs/integrations/consul/acl.mdx new file mode 100644 index 000000000..7f1e85ebf --- /dev/null +++ b/website/content/docs/integrations/consul/acl.mdx @@ -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. + + + + +```hcl +agent_prefix "" { + policy = "read" +} + +node_prefix "" { + policy = "read" +} + +service_prefix "" { + policy = "write" +} + +mesh = "write" +``` + + + + +```hcl +agent_prefix "" { + policy = "read" +} + +node_prefix "" { + policy = "read" +} + +service_prefix "" { + policy = "write" +} +``` + + + + +## 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. + + + +```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" + } +} +``` + + + +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. + + + +```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" + } +} +``` + + + +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. + + + +```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" + } +} +``` + + + +#### 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 + +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. + + + +```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"] + } + } + } +} +``` + + + +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" +} +``` + + + +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). + + + +## 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 diff --git a/website/content/docs/integrations/consul/index.mdx b/website/content/docs/integrations/consul/index.mdx new file mode 100644 index 000000000..ce75f5a93 --- /dev/null +++ b/website/content/docs/integrations/consul/index.mdx @@ -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 + +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 + +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" diff --git a/website/content/docs/integrations/consul-connect.mdx b/website/content/docs/integrations/consul/service-mesh.mdx similarity index 100% rename from website/content/docs/integrations/consul-connect.mdx rename to website/content/docs/integrations/consul/service-mesh.mdx diff --git a/website/content/docs/integrations/vault-integration.mdx b/website/content/docs/integrations/vault/acl.mdx similarity index 56% rename from website/content/docs/integrations/vault-integration.mdx rename to website/content/docs/integrations/vault/acl.mdx index fd897c29a..b649476d0 100644 --- a/website/content/docs/integrations/vault-integration.mdx +++ b/website/content/docs/integrations/vault/acl.mdx @@ -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. - +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 - +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. + ```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. + -```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`][]. + + + +```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`. + -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 + + +```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. + + +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. + + + +```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 +} +``` + + + +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. + + + +```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 +} +``` + + + +#### 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. + + + +```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 +} +``` + + + +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///*`, where `` and `` are read from the workload identity claims +`nomad_namespace` and `nomad_job_id`. + + ```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. + -```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 + +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.** - + 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). @@ -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 diff --git a/website/content/docs/integrations/vault/index.mdx b/website/content/docs/integrations/vault/index.mdx new file mode 100644 index 000000000..b8d58e31a --- /dev/null +++ b/website/content/docs/integrations/vault/index.mdx @@ -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 + +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 diff --git a/website/content/docs/job-specification/identity.mdx b/website/content/docs/job-specification/identity.mdx index bc8ca05c4..ec2299274 100644 --- a/website/content/docs/job-specification/identity.mdx +++ b/website/content/docs/job-specification/identity.mdx @@ -10,7 +10,9 @@ description: |- @@ -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_`. Identities for services do not need to specify a +`name`. + +In Nomad Community Edition, `` is always `default`, so the task +identity name should be `consul_default`. + + + Nomad Enterprise supports multiple Consul clusters. The value of + <cluster_name> must be the same as the + consul.cluster value for the task. + + +Refer to [Nomad Workload Identities][int_consul_wid] section of the Consul +integration documentation for more information. + + + + + +```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" + } + } + } +} +``` + + + + + + +```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" + } + } + } +} +``` + + + + + +## 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_`. + +In Nomad Community Edition, `` is always `default`, so the +identity name should be `vault_default`. + + + Nomad Enterprise supports multiple Vault clusters. The value of + <cluster_name> must be the same as the + vault.cluster value for the task. + + +Refer to [Nomad Workload Identities][int_vault_wid] section of the Vault +integration documentation for more information. + + + + + +```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 = < + + + + +```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 = < + + + [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/ diff --git a/website/data/docs-nav-data.json b/website/data/docs-nav-data.json index c4140f13a..5516d4253 100644 --- a/website/data/docs-nav-data.json +++ b/website/data/docs-nav-data.json @@ -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" + } + ] } ] }, diff --git a/website/public/img/consul-integration-auth-method.png b/website/public/img/consul-integration-auth-method.png new file mode 100644 index 000000000..51598cb4d Binary files /dev/null and b/website/public/img/consul-integration-auth-method.png differ diff --git a/website/public/img/consul-integration-wi.png b/website/public/img/consul-integration-wi.png new file mode 100644 index 000000000..81058f5ae Binary files /dev/null and b/website/public/img/consul-integration-wi.png differ diff --git a/website/public/img/consul-integration-wid-acl-token.png b/website/public/img/consul-integration-wid-acl-token.png new file mode 100644 index 000000000..d74576f35 Binary files /dev/null and b/website/public/img/consul-integration-wid-acl-token.png differ diff --git a/website/public/img/vault-integration-auth-method.png b/website/public/img/vault-integration-auth-method.png new file mode 100644 index 000000000..c7b063b18 Binary files /dev/null and b/website/public/img/vault-integration-auth-method.png differ diff --git a/website/public/img/vault-integration-auth-overview.png b/website/public/img/vault-integration-auth-overview.png new file mode 100644 index 000000000..e923f64eb Binary files /dev/null and b/website/public/img/vault-integration-auth-overview.png differ diff --git a/website/public/img/vault-integration-wid-acl-token.png b/website/public/img/vault-integration-wid-acl-token.png new file mode 100644 index 000000000..cc6e862ad Binary files /dev/null and b/website/public/img/vault-integration-wid-acl-token.png differ diff --git a/website/redirects.js b/website/redirects.js index 0b1f858e1..e03c6cdc8 100644 --- a/website/redirects.js +++ b/website/redirects.js @@ -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, + }, ]