【Azure】Blobのバージョン管理有効時における削除動作の整理

Azure Blobストレージには複数のデータ保護機能がありますが、「Blob の論理的な削除」と「Blobのバージョン管理」を組み合わせた際のBlob削除動作で混乱したので、検証して整理してみました。

# 各機能の概要
## Blobの論理的な削除
Blobの論理的な削除を有効にしていると、Blobを削除してもすぐに完全削除されず、削除フラグが立っただけの状態になります。指定した日数が経過すると完全に削除されます。完全削除される前であれば削除を取り消すことができます。

## バージョン管理
バージョン管理を有効にしていると、Blobに変更を加えるたびにバージョンが作成されます。バージョンを指定してBlobを復元することができる、という機能です。

![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/06cd3f9b-c22a-a687-af06-49c41d32c553.png)

バージョンは消さない限り残り続けます。一定期間で自動的に削除されるようにするには、指定期間が経過するとバージョンを削除するライフサイクル管理の設定が必要です。バージョンの分だけコストが余分にかかるので、バージョンをずっと残す必要がない限りはライフサイクル管理設定をセットで入れるべきでしょう。

昔はライフサイクル管理の設定を手動でおこなう必要がありましたが、今はバージョン管理を有効化するときに「(数日) 後にバージョンを削除する」を指定しておけばライフサイクル管理の設定を自動作成してくれるようになりました。

↓ こんな設定が自動作成されます
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/c91d9ca0-605a-0b89-fc74-c0ce3d35ead0.png)
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/8998edb2-dc4d-1339-ca15-37c104348ed6.png)

# Blobを削除した際の挙動
## バージョン管理有効時のBlob削除

バージョン管理を有効にした状態でBlobを消すと「削除済み」状態ではなく、「以前のバージョン」という状態に遷移します。ここがちょっとわかりにくい点です。
![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/66318558-4588-4af4-635b-6d1741338934.png)

Blobを削除すると、削除時点の状態が新しいバージョンとして追加されます。「削除されたBlobを表示」にチェックを入れると削除したBlobが一覧に表示されますが、このBlobの状態は「削除済み」ではなく、「以前のバージョン」という状態になっていることが確認できます。一覧に表示されているBlobは削除時点のバージョンを指しているので「以前のバージョン」という状態扱いになるのかなと推察します。

![図2_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/a30e444d-1081-bc69-bf85-3bcb4b4033c7.png)

Microsoftの公式ドキュメントにもこの動作について記載がありますが、読むとわかったようなわからないような気持ちになります。
[削除操作でのバージョン管理](https://learn.microsoft.com/ja-jp/azure/storage/blobs/versioning-overview#versioning-on-delete-operations)

## 論理的な削除とバージョン管理が有効であるときの挙動

ここがハマったポイントです。論理的な削除で指定している保持期間が経過したら、削除したBlobが完全に消えると想定していたのですが、消えませんでした。

検証してみて判明しましたが、「論理的な削除」と「バージョン管理」を両方有効にしている時は以下のような挙動になるようです。
* バージョンにも論理的な削除が適用される。そのため、バージョンを消すとバージョンは削除済み状態に遷移する。「論理的な削除」で指定している期間が経過すると削除済みのバージョンが完全に消える
* すべてのバージョンが削除済み状態になるとBlobも削除済み扱いとなる。この状態から「論理的な削除」で指定している期間が経過すると完全にBlobが削除される
 
単純にBlobを削除しただけだとBlobが完全に消えるまでの日数は**バージョンを削除するライフサイクル管理で指定している日数＋論理的な削除で指定している保持期間**となります。

試していないですが、ライフサイクル管理でバージョンを削除する設定が入っていないと消したBlobが論理削除状態で残り続けるでしょうね…。

早めにBlobを完全削除させたければBlobを削除した後にバージョンを全部削除する、という操作を行えばよいです。「論理的な削除」で指定している期間が経過したらBlobが完全削除されます。

公式ドキュメントにこの挙動に関する記述があるのですが、上の動きになることを理解してから読まないと書いてある内容がピンときません。。

> ストレージ アカウントに対してバージョン管理と論理的な削除の両方が有効になっている場合、ある BLOB を削除すると、その BLOB の現在のバージョンが以前のバージョンになります。 新しいバージョンは作成されず、論理的に削除されたスナップショットは作成されません。 削除された BLOB に対しては、論理的な削除の保持期間は適用されません。
　
> 論理的な削除では、BLOB のバージョンを削除するための追加の保護が提供されます。 以前のバージョンの BLOB を削除すると、そのバージョンは論理的に削除されます。 論理的に削除されたバージョンは、論理的な削除の保持期間が経過するまで保持され、経過すると完全に削除されます。

引用元：[BLOB またはバージョンの削除](https://learn.microsoft.com/ja-jp/azure/storage/blobs/versioning-overview#deleting-a-blob-or-version)

## バージョン管理のみ有効であるときの挙動
論理的な削除は無効にして、バージョン管理のみ有効にするとどうなるかも確認しました。

検証してみたところ、Blobを消してもすべてのバージョンを消さないとBlobが完全削除されない動きになりました。少なくともBlobを削除するとその時点のバージョンが追加されるので、この仕組みを理解していないとBlobを消したつもりが実際は残り続けている…ということになりかねないです。ライフサイクル管理を意図的に設定していない場合は特に注意が必要ですね。

# 実際に試してみた際の挙動例 
### 設定
* BLOB の論理的な削除：有効
削除した BLOB の保持期間 (日数)：1日
* BLOB のバージョン管理：有効
3日後にバージョンを削除する

### テストファイル
3つのテストファイルを用意します。それぞれのファイルに3回ずつ書き込み操作をおこない、バージョンを3つ作っておきます。挙動を確認するため、それぞれのファイルに対して以下の操作を行います。

| ファイル名 | 操作 |
|:-:|:-|
| test1.txt  | Blobを削除し、削除した時に作成されるバージョンを手動削除  |
| test2.txt  | Blobを削除し、他には操作しない  |
| test3.txt  | Blobを削除し、すべてのバージョンを手動削除  |

### 検証開始時点
test1.txtとtest3.txtが削除状態となっています。
test2.txtは以前のバージョン状態となっています。
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/91c89dff-8808-22f7-7d2d-6655be725df3.png)
![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/43a74816-a159-28bc-65ab-5b850ad482c2.png)
![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/9cdd7a06-bb5d-a609-f0d4-6683186a28d1.png)
![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/497157d5-a23a-9049-8744-63bfb64000f5.png)

### 1日経過時点
全てのバージョンを削除していたtest3.txtは完全に削除されました。
test1.txtは削除していたバージョンのみ削除され、状態は「以前のバージョン」になりました。
test2.txtは変化なしです。
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/99dcdf0a-a1b9-9e78-5fc7-b48325172b4a.png)
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/bf9ef8cf-dd93-0fc6-c4a2-b183aab3a67e.png)
![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/fccfe4db-854e-7bec-e686-2a06bdb9a69c.png)

### 3日経過時点
test1.txt、test2.txtともに削除済み状態になりました。
ライフサイクル管理によりすべてのバージョンは削除済みになっています。
![01-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/50f60fd1-f681-2e9f-25d7-37dfd3babd6e.png)
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/726b3ae6-db24-e85f-1421-e3f1ae987798.png)
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/a76ffec1-ab85-522b-6fd5-79846ab45341.png)

### 4日経過時点
完全にBlobが削除されました。
![01-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2850747/b07ba3ca-79dd-e496-e09d-e17aa7af7d33.png)


# まとめ
検証結果をまとめると、以下のようになるかと思います。
* バージョン管理を使うときはライフサイクル管理の削除設定との併用が推奨
* バージョン管理が有効な場合はバージョンがすべて削除されないとBlobが完全に消えない
* Blobの論理的な削除を有効にすると、バージョンにも論理的な削除が適用される。すべてのバージョンが削除済み状態になってから「論理的な削除」で指定している期間が経過すると完全にBlobが削除される
* Blobが完全に消えるまでの日数は最大で「バージョンを削除するライフサイクル管理で指定している日数＋論理的な削除で指定している保持期間」

Blobのバージョン管理は気を付けないとハマるポイントがいろいろあることがわかりました。特に論理的な削除と組み合わせると仕組みが複雑になりますね。使い方や規模によっては課金への影響が大きいと思われるので気を付ける必要があります。