<a id="manage-storage"></a>

# How to manage storage

See also: [Storage](https://documentation.ubuntu.com/juju/4.0/reference/storage.md#storage)

This document shows how to manage storage. This will enable you to allocate resources at a granular level and can be useful in optimizing the deployment of an application. The level of sophistication is limited by your cloud (whether it supports dynamic storage or storage configuration attributes),
and by the charm in charge of that application (whether it supports storage persistence, additional cache, etc.).

<a id="add-storage"></a>

## Add storage

Assuming the storage provider supports it, you can create and attach storage instances to units in a specific way by using `juju add-storage`.

First, identify the application unit to which you wish to attach the storage. As an example, suppose we want to target unit 0 of `ceph-osd`, that is, `ceph-osd/0`.

Second, prepare a storage directive for your desired storage. For example, given the `ceph-osd` charm and assuming we are in an AWS model, we might have `osd-devices=ebs, 32G, 1`.

Finally, run the `add-storage` command passing as arguments the unit to which storage is to be attached and the storage directive. Drawing on our steps before, we can create a 32GiB EBS volume and attach it to unit `ceph-osd/0` as its OSD storage as below:

```text
juju add-storage ceph-osd/0 osd-devices=ebs,32G,1
```

Juju will ensure the storage is allowed to attach to the unit’s machine.

#### CAUTION
The above only works if the volume is in the same availability zone as the instance. This is a requirement that comes from the `ebs` storage provider. See more: [ebs](https://documentation.ubuntu.com/juju/4.0/reference/cloud/list-of-supported-clouds/amazon-ec2.md#storage-provider-ebs).

See more:  [Storage directive](https://documentation.ubuntu.com/juju/4.0/reference/storage.md#storage-directive), [juju add-storage](https://documentation.ubuntu.com/juju/4.0/reference/juju-cli/list-of-juju-cli-commands/add-storage.md#command-juju-add-storage)

You can also create and attach storage during deployment by running the `deploy` command with a `--storage` option followed by your desired storage directive. For example, suppose you have an AWS model, you want to deploy the `postgresql` charm on it, and you’ve already identified a suitable storage directive of the form `pgdata=iops,100G` (suppose `iops` is a version of `ebs` with 30 IOPS). You can use all of these in one go as below. This will create a 3000 IOPS storage volume (100GiB x 30IOPS/GiB (x 1)) and attach it to the newly deployed PostgreSQL as its database storage.

```text
juju deploy postgresql --storage pgdata=iops,100G
```

#### CAUTION
Charms might specify a maximum number of storage instances. For example, in the case of the `postgresql` charm, a maximum of one is allowed for `pgdata`. If an attempt is made to exceed it, Juju will return an error.

See more: [juju deploy](https://documentation.ubuntu.com/juju/4.0/reference/juju-cli/list-of-juju-cli-commands/deploy.md#command-juju-deploy)

And you can also create and attach storage while upgrading a charm.

#### NOTE
Specifying new storage direectives may be necessary when upgrading to a revision of a charm that introduces new, required, storage options.

The logic is entirely parallel to the case where this was done while deploying a charm – you do this by running the `refresh` command with the `--storage` option followed by a suitable  storage directive, e.g., `pgdata=10G`, as shown below. This will change any existing directives or define new ones (for example, in the case where the storage option did not exist in the version of the charm before the upgrade). If you don’t specify any directives, the defaults will kick in.

```text
juju refresh postgresql --storage pgdata=10G
```

See more: [juju refresh](https://documentation.ubuntu.com/juju/4.0/reference/juju-cli/list-of-juju-cli-commands/refresh.md#command-juju-refresh)

<a id="view-the-available-storage"></a>

## View the available storage

TBA

See more: [juju storage](https://documentation.ubuntu.com/juju/4.0/reference/juju-cli/list-of-juju-cli-commands/storage.md#command-juju-storage)

<a id="view-storage-details"></a>

## View storage details

TBA

See more: [juju show-storage](https://documentation.ubuntu.com/juju/4.0/reference/juju-cli/list-of-juju-cli-commands/show-storage.md#command-juju-show-storage)

<a id="detach-storage"></a>

## Detach storage

If the storage is dynamic, you can detach it from units by running `juju detach-storage` followed by the unit you want to detach. For example, to detach OSD device `osd-devices/2` from a Ceph unit, do:

```text
juju detach-storage osd-devices/2
```

#### CAUTION
Charms might define a minimum number of storage instances. For example, the `postgresql` charm specifies a minimum of zero for its `pgdata`. If detaching storage from a unit would bring the total number of storage instances below the minimum, Juju will return an error.

#### NOTE
Detaching storage from a unit does not destroy the storage.

See more: [juju detach-storage](https://documentation.ubuntu.com/juju/4.0/reference/juju-cli/list-of-juju-cli-commands/detach-storage.md#command-juju-detach-storage)

<a id="attach-storage"></a>

## Attach storage

Detaching storage does not destroy the storage. In addition, when a unit is removed from a model, and the unit has dynamic storage attached, the storage will be detached and left intact. This allows detached storage to be re-attached to an existing unit. This can be done during deployment / when you’re adding a unit / at any time, as shown below:

To deploy PostgreSQL with (detached) existing storage `pgdata/0`:

```text
juju deploy postgresql --attach-storage pgdata/0
```

See more: [juju deploy](https://documentation.ubuntu.com/juju/4.0/reference/juju-cli/list-of-juju-cli-commands/deploy.md#command-juju-deploy)

To add a new Ceph OSD unit with (detached) existing storage `osd-devices/2`:

```text
juju add-unit ceph-osd --attach-storage osd-devices/2
```

#### NOTE
The `--attach-storage` and `-n` flags cannot be used together.

See more: [juju add-unit](https://documentation.ubuntu.com/juju/4.0/reference/juju-cli/list-of-juju-cli-commands/add-unit.md#command-juju-add-unit)

To attach existing storage `osd-devices/7` to existing unit `ceph-osd/1`:

```text
juju attach-storage ceph-osd/1 osd-devices/7
```

See more: [juju attach-storage](https://documentation.ubuntu.com/juju/4.0/reference/juju-cli/list-of-juju-cli-commands/attach-storage.md#command-juju-attach-storage)

<a id="reuse-storage"></a>

## Reuse storage

#### IMPORTANT
This feature is not implemented in Juju 4.0.0 but should be back in future versions.

If you’ve destroyed a model but kept the storage, you’ll likely want to reuse it. You can do this by running the `juju import-filesystem` command followed by the storage provider, the provider ID, and the storage name. For example, given an AWS model (with the storage provider `ebs`), a provider ID `vol-123456`, and a storage name `pgdata`, this is as below:

```text
juju add-model default
juju import-filesystem aws vol-123456 pgdata
```

Note: The determination of the provider ID  is dependent upon the cloud type. A provider ID from another cloud may look entirely different.

See more: [juju import-filesystem](https://documentation.ubuntu.com/juju/4.0/reference/juju-cli/list-of-juju-cli-commands/import-filesystem.md#command-juju-import-filesystem), [lxd](https://documentation.ubuntu.com/juju/4.0/reference/cloud/list-of-supported-clouds/lxd.md#storage-provider-lxd)

<a id="remove-storage"></a>

## Remove storage

See also: [Removing things](https://documentation.ubuntu.com/juju/4.0/reference/removing-things.md#removing-things)

The underlying cloud’s storage resource is normally destroyed by first detaching it and then using `juju remove-storage`. For example, assuming the `osd-devices/3` storage instance has already been detached, the code below will remove it from the model. It will also be automatically destroyed on the cloud provider.

```text
juju remove-storage osd-devices/3
```

### Example scenario: storage upgrade

To upgrade the OSD journal of Ceph unit `ceph-osd/0` from magnetic to solid state (SSD) and dispose of the unneeded original journal `osd-journals/0`:

```text
juju add-storage ceph-osd/0 osd-journals=ebs-ssd,8G,1
juju detach-storage osd-journals/0
juju remove-storage osd-journals/0
```

#### IMPORTANT
You can also remove storage from the model and prevent it being destroyed on the cloud provider by passing the `--no-destroy` flag. However, be wary of using  this option as Juju will lose sight of the volume and it will only be visible from the cloud provider.

If an attempt is made to either attach or remove storage that is currently in use (i.e. it is attached to a unit) Juju will return an error. To remove currently attached storage from the model the `--force` option must be used. For example,

```text
juju remove-storage --force pgdata/1
```

See more: [juju remove-storage](https://documentation.ubuntu.com/juju/4.0/reference/juju-cli/list-of-juju-cli-commands/remove-storage.md#command-juju-remove-storage)

Finally, a model cannot be destroyed while storage volumes remain without passing a special option (`--release-storage` to detach all volumes and `--destroy-storage` to remove all volumes). You can handle this by either destroying the storage or releasing it (so you can later attach it to something else), as shown below:

```text
# Destroy the model along with all existing storage volumes:
juju destroy-model default --destroy-storage

# Destroy the model while keeping intact all the storage volumes:
juju destroy-model default --release-storage
```

See more: [juju destroy-model](https://documentation.ubuntu.com/juju/4.0/reference/juju-cli/list-of-juju-cli-commands/destroy-model.md#command-juju-destroy-model)

Naturally, this applies to the removal of a controller as well.

To destroy a controller (and its models) along with all existing storage volumes:

```text
# Destroy the controller along with all existing storage volumes:
juju destroy-controller lxd-controller --destroy-all-models --destroy-storage

# Destroy the controller while keeping intact all the storage volumes:
juju destroy-controller lxd-controller --destroy-all-models --release-storage
```

See more: [juju destroy-controller](https://documentation.ubuntu.com/juju/4.0/reference/juju-cli/list-of-juju-cli-commands/destroy-controller.md#command-juju-destroy-controller)
