---
layout: docs
page_title: 'Commands: volume register'
description: |
  Register volumes with CSI plugins.
---

# Command: volume register

The `volume register` command registers external storage volumes with Nomad's
[Container Storage Interface (CSI)][csi] support. The volume must exist on the
remote storage provider before it can be registered and used by a task.

CSI plugins that implement the [Controller][csi_plugins_internals] interface
can be created via the [`volume create`] command, which will automatically
register the volume as well.

## Usage

```plaintext
nomad volume register [options] [file]
```

The `volume register` command requires a single argument, specifying the path
to a file containing a valid [volume
specification][volume_specification]. This file will be read and the job will
be submitted to Nomad for scheduling. If the supplied path is "-", the job
file is read from STDIN. Otherwise it is read from the file at the supplied
path.

When ACLs are enabled, this command requires a token with the
`csi-write-volume` capability for the volume's namespace.

## General Options

@include 'general_options.mdx'

## Volume Specification

The file may be provided as either HCL or JSON. An example HCL configuration:

```hcl
id              = "ebs_prod_db1"
name            = "database"
type            = "csi"
external_id     = "vol-23452345"
plugin_id       = "ebs-prod"

capability {
  access_mode     = "single-node-reader-only"
  attachment_mode = "file-system"
}

capability {
  access_mode     = "single-node-writer"
  attachment_mode = "file-system"
}

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

topology_request {
  required {
    topology { segments { "rack" = "R2" } }
    topology { segments { "rack" = "R1", "zone" = "us-east-1a"} }
  }
}

secrets {
  example_secret = "xyzzy"
}

parameters {
  skuname = "Premium_LRS"
}

context {
  endpoint = "http://192.168.1.101:9425"
}
```

## Volume Specification Parameters

- `id` `(string: <required>)` - The unique ID of the volume. This is how the
  [`volume.source`][csi_volume_source] field in a job specification will refer
  to the volume.

- `namespace` `(string: <optional>)` - The namespace of the volume. This field
  overrides the namespace provided by the `-namespace` flag or `NOMAD_NAMESPACE`
  environment variable. Defaults to `"default"` if unset.

- `name` `(string: <required>)` - The display name of the volume.

- `type` `(string: <required>)` - The type of volume. Currently only `"csi"`
  is supported.

- `external_id` `(string: <required>)` - The ID of the physical volume from
  the storage provider. For example, the volume ID of an AWS EBS volume or
  Digital Ocean volume.

- `plugin_id` `(string: <required>)` - The ID of the [CSI plugin][csi_plugin]
  that manages this volume.

- `capability` `(Capability: <required>)` - Option for validating the
  capability of a volume. You must provide at least one `capability` block, and
  you must provide a block for each capability you intend to use in a job's
  [`volume`] block. Each `capability` block must have the following fields:

  - `access_mode` `(string: <required>)` - Defines whether a volume should be
    available concurrently. Can be one of `"single-node-reader-only"`,
    `"single-node-writer"`, `"multi-node-reader-only"`,
    `"multi-node-single-writer"`, or `"multi-node-multi-writer"`. Most CSI
    plugins support only single-node modes. Consult the documentation of the
    storage provider and CSI plugin.

  - `attachment_mode` `(string: <required>)` - The storage API that will be used
    by the volume. Most storage providers will support `"file-system"`, to mount
    volumes using the CSI filesystem API. Some storage providers will support
    `"block-device"`, which will mount the volume with the CSI block device API
    within the container.

- `mount_options` - Options for mounting `file-system` volumes that don't
  already have a pre-formatted file system. This block will be validated
  during volume creation against the `capability` field. The `mount_options`
  provided in a job specification's [`volume`] block will override this
  block. 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"`)

- `topology_request` <code>([TopologyRequest](#topology_request-parameters): nil)</code> -
  Specify locations (region, zone, rack, etc.)  where the provisioned
  volume is accessible from. Consult the documentation for your
  storage provider and CSI plugin as to whether it supports defining
  topology and what values it expects for topology
  segments. Specifying topology segments that aren't supported by the
  storage provider may return an error or may be silently removed by
  the plugin.

- `secrets` <code>(map<string|string>:nil)</code> - An optional
  key-value map of strings used as credentials for publishing and
  unpublishing volumes.

- `parameters` <code>(map<string|string>:nil)</code> - An optional
  key-value map of strings passed directly to the CSI plugin to
  configure the volume. The details of these parameters are specific
  to each storage provider, so please see the specific plugin
  documentation for more information.

- `context` <code>(map<string|string>:nil)</code> - An optional
  key-value map of strings passed directly to the CSI plugin to
  validate the volume. The details of these parameters are specific to
  each storage provider, so please see the specific plugin
  documentation for more information.

### `topology_request` Parameters

For the `topology_request` field, you may specify a list of `required`
topologies. The `required` topologies indicate that the volume was
created in a location accessible from all the listed topologies.

Note this behavior is different from the `nomad volume create`
command, because the volume has already been created and you are
defining the topology for Nomad. The `register` command does not
support setting `preferred` topologies.

Each topology listed has a single field:

- `segments` `(map[string]string)` - A map of location types to their
 values. The specific fields required are defined by the CSI
 plugin. For example, a plugin might require defining both a rack and
 a zone: `segments {rack = "R2", zone = "us-east-1a"}`.

For example:

```hcl
topology_request {
  required {
    topology { segments { "rack" = "R1", "zone" = "us-east-1a" } }
    topology { segments { "rack" = "R2", "zone" = "us-east-1a" } }
  }
}
```

This configuration indicates that the volume is accessible from both
racks `R1` or `R2`.

### Unused Fields

Note that several fields used in the [`volume create`] command are set
automatically by the plugin when `volume create` is successful and cannot be
set on a pre-existing volume. You should not set the `snapshot_id`,
`clone_id`, `capacity_min`, or `capacity_max` fields described on that page.

[csi]: https://github.com/container-storage-interface/spec
[csi_plugins_internals]: /docs/internals/plugins/csi#csi-plugins
[volume_specification]: #volume-specification
[csi_plugin]: /docs/job-specification/csi_plugin
[csi_volume_source]: /docs/job-specification/volume#source
[`volume`]: /docs/job-specification/volume
[`volume create`]: /docs/commands/volume/create
