Nomad
volume block in the job specification
| Placement | 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.
job "docs" {
  group "example" {
    volume "certs" {
      type      = "host"
      source    = "ca-certificates"
      read_only = true
    }
  }
}
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 configured on the
client, dynamic host volumes created via volume create or volume
register, or CSI volumes dynamically mounted by CSI
plugins.
The Nomad client makes the volumes available to tasks according to
the volume_mount block in the task configuration.
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- csivolumes, 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_onlyconfiguration. This value is also used for validating- host_volumeACLs and for scheduling when a matching- host_volumerequires- read_onlyusage.
- 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- stickyfield for dynamic host volumes. For CSI volumes, the- per_allocfield provides similar functionality
- per_alloc- (bool: false)- Specifies that the- sourceof the volume should have the suffix- [n], where- nis 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- myvolumeand- per_alloc = true, the allocation named- myjob.mygroup.mytask[0]will require a volume ID- myvolume[0].- The - per_allocfield cannot be true for system jobs, sysbatch jobs, or jobs that use canaries.- per_allocis mutually exclusive with the- stickyproperty. Use- per_alloconly with CSI volumes and- stickyonly 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_modeand- attachment_modetogether must exactly match one of the volume's- capabilityblocks.- For CSI volumes the - access_modeis 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_modeis optional. Can be one of the following:- Defaults to - single-node-writerunless- 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_modeand- attachment_modetogether must exactly match one of the volume's- capabilityblocks.- For CSI volumes the - attachment_modefield 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_modefield 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-systemattachment mode. These options override the- mount_optionsfield 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.
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.
$ 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