---
layout: docs
page_title: volume Block - Job Specification
description: >-
  Configure storage volumes in the "volume" block of a Nomad job specification. Specify dynamic host or Container Storage Interface (CSI) volume type, node access mode, filesystem or block device attachment mode, and mount options. Enable read only access and mounting a unique volume per node. Learn about volume interpolation.
---

# `volume` Block

<Placement groups={['job', 'group', 'volume']} />

The `volume` block allows the group to specify that it requires a
given volume from the cluster.

The key of the block is the name of the volume as it will be exposed
to task configuration.

```hcl
job "docs" {
  group "example" {
    volume "certs" {
      type      = "host"
      source    = "ca-certificates"
      read_only = true
    }
  }
}
```

```hcl
job "docs" {
  group "example" {
    volume "data" {
      type            = "csi"
      source          = "csi-volume"
      read_only       = true
      attachment_mode = "file-system"
      access_mode     = "single-node-writer"
      per_alloc       = true

      mount_options {
        fs_type     = "ext4"
        mount_flags = ["noatime"]
      }
    }
  }
}
```


The Nomad server ensures that the allocations are only scheduled on hosts
that have a set of volumes that meet the criteria specified in the `volume`
blocks. These may be [static host volumes][host_volume] configured on the
client, [dynamic host volumes][] created via [`volume create`][] or [`volume
register`][], or [CSI volumes][csi_volume] dynamically mounted by [CSI
plugins][csi_plugin].

The Nomad client makes the volumes available to tasks according to
the [volume_mount][volume_mount] block in the `task` configuration.

## `volume` Parameters

- `type` `(string: "")` - Specifies the type of a given volume. The valid volume
  types are `"host"` and `"csi"`. Setting the `"host"` value can request either
  statically configured host volumes or dynamic host volumes, depending on what
  is available on a given node.

- `source` `(string: <required>)` - The name of the volume to
  request. When using `host_volume`'s this should match the published
  name of the host volume. When using `csi` volumes, this should match
  the ID of the registered volume.

- `read_only` `(bool: false)` - Specifies that the group only requires
  read only access to a volume and is used as the default value for
  the `volume_mount -> read_only` configuration. This value is also
  used for validating `host_volume` ACLs and for scheduling when a
  matching `host_volume` requires `read_only` usage.

- `sticky` `(bool: false)` - Specifies that this volume sticks to the allocation
  that uses it. Upon every reschedule and replacement, the task
  group always receives the volume with the same ID, if available. Use sticky
  volumes for [stateful deployments]. You may only use the `sticky` field for
  dynamic host volumes. For CSI volumes, the `per_alloc` field provides similar
  functionality

- `per_alloc` `(bool: false)` - Specifies that the `source` of the volume
  should have the suffix `[n]`, where `n` is the allocation index. This allows
  mounting a unique volume per allocation, so long as the volume's source is
  named appropriately. For example, with the source `myvolume` and `per_alloc
  = true`, the allocation named `myjob.mygroup.mytask[0]` will require a
  volume ID `myvolume[0]`.

  The `per_alloc` field cannot be true for system jobs, sysbatch jobs, or jobs
  that use canaries. `per_alloc` is mutually exclusive with the `sticky`
  property. Use `per_alloc` only with CSI volumes and `sticky` only
  with dynamic host volumes.

The following fields are only valid for volumes with `type = "csi"` or dynamic
host volumes with `type = "host"`:

- `access_mode` `(string)` - Defines whether a volume should be
  available concurrently. The `access_mode` and `attachment_mode` together
  must exactly match one of the volume's `capability` blocks.

  - For CSI volumes the `access_mode` is required. Can be one of the following:

    - `"single-node-reader-only"`
    - `"single-node-writer"`
    - `"multi-node-reader-only"`
    - `"multi-node-single-writer"`
    - `"multi-node-multi-writer"`

    Most CSI plugins support only single-node modes.
    Consult the documentation of the storage provider and CSI plugin.

  - For dynamic host volumes the `access_mode` is optional. Can be one of the following:

    - `"single-node-writer"`
    - `"single-node-reader-only"`
    - `"single-node-single-writer"`
    - `"single-node-multi-writer"`

    Defaults to `single-node-writer` unless `read_only = true`, in which case it
    defaults to `single-node-reader-only`.

- `attachment_mode` `(string)` - The storage API used by the
  volume. One of `"file-system"` or `"block-device"`. The `access_mode` and
  `attachment_mode` together must exactly match one of the volume's `capability`
  blocks.

  - For CSI volumes the `attachment_mode` field is required. Most storage
    providers support `"file-system"`, to mount volumes using the CSI
    filesystem API. Some storage providers support `"block-device"`, which
    mounts the volume with the CSI block device API within the container.

  - For dynamic host volumes the `attachment_mode` field is optional and
    defaults to `"file-system"`.

The following fields are only valid for volumes with `type = "csi"`:

- `mount_options` - Options for mounting CSI volumes that have the
  `file-system` [attachment mode]. These options override the `mount_options`
  field from [volume registration]. Consult the documentation for your storage
  provider and CSI plugin as to whether these options are required or
  necessary.

  - `fs_type`: file system type (ex. `"ext4"`)
  - `mount_flags`: the flags passed to `mount` (ex. `["ro", "noatime"]`)

## Volume Interpolation

Because volumes represent state, many workloads with multiple allocations will
want to mount specific volumes to specific tasks. The `volume` block is used
to schedule workloads, so `${NOMAD_ALLOC_INDEX}` can't be used directly in the
`volume.source` field. The following job specification demonstrates how to use
multiple volumes with multiple allocations, using the `per_alloc` field. This
job specification also shows using HCL2 -variables interpolation to expose
information to the task's environment.

```hcl
variables {
  path = "test"
}

job "example" {
  datacenters = ["dc1"]

  group "cache" {

    count = 2

    volume "cache-volume" {
      type            = "csi"
      source          = "test-volume"
      attachment_mode = "file-system"
      access_mode     = "single-node-writer"
      per_alloc       = true
    }

    network {
      port "db" {
        to = 6379
      }
    }

    task "redis" {
      driver = "docker"
      config {
        image = "redis:7"
        ports = ["db"]
      }
      resources {
        cpu    = 500
        memory = 256
      }

      env {
        # this will be available as the MOUNT_PATH environment
        # variable in the task
        MOUNT_PATH = "${NOMAD_ALLOC_DIR}/${var.path}"
      }

      volume_mount {
        volume      = "cache-volume"
        destination = "${NOMAD_ALLOC_DIR}/${var.path}"
      }

    }
  }
}
```

The job that results from this job specification has two task groups, each one
named for each of the two volumes. Each allocation has its own volume.

```shell-session
$ nomad job status example
ID            = example
...

Allocations
ID        Node ID   Task Group  Version  Desired  Status   Created  Modified
81d32909  352c6926  cache-1     0        run      running  4s ago   3s ago
ce6fbfc8  352c6926  cache-0     0        run      running  4s ago   3s ago

$ nomad volume status 'test-volume[0]'
...
Allocations
ID        Node ID   Task Group  Version  Desired  Status   Created  Modified
ce6fbfc8  352c6926  cache-0     0        run      running  29s ago  18s ago

$ nomad volume status 'test-volume[1]'
...
Allocations
ID        Node ID   Task Group  Version  Desired  Status   Created  Modified
81d32909  352c6926  cache-0     0        run      running  29s ago  18s ago
```

[volume_mount]: /nomad/docs/job-specification/volume_mount 'Nomad volume_mount Job Specification'
[host_volume]: /nomad/docs/configuration/client#host_volume-block
[csi_volume]: /nomad/docs/commands/volume/register
[csi_plugin]: /nomad/docs/job-specification/csi_plugin
[csi_volume]: /nomad/docs/commands/volume/register
[attachment mode]: /nomad/docs/commands/volume/register#attachment_mode
[volume registration]: /nomad/docs/commands/volume/register#mount_options
[dynamic host volumes]: /nomad/docs/other-specifications/volume/host
[stateful deployments]: /nomad/docs/concepts/stateful-deployments
[`volume create`]: /nomad/docs/commands/volume/create
[`volume register`]: /nomad/docs/commands/volume/register
