Check! Azure Blob Storage で、リースを使って意図しない変更や削除を防ごう

こんにちは、 @dz_ こと大平かづみです。

Prologue - はじめに
====

いつごろから利用できるようになった Azure Blob Storage の「リース」についてまとめました。

Azure Blob Storage のリースとは？
====
ざっくりいうと、 リースを取得すると、Blob のコンテナや個々のファイルに対してロックすることができます。リース中は、変更や削除を防止することができ、リース期間を指定することもできます。

Azure  ポータル、REST API、 CLI から利用できます。

- Azure ポータル
    - [Support for blob storage lease management from the Azure portal](https://azure.microsoft.com/en-us/updates/support-for-blob-storage-lease-management-from-azure-portal/)
- REST API
    - [Lease Container | Microsoft Docs](https://docs.microsoft.com/en-us/rest/api/storageservices/lease-container)
    - [Lease Blob | Microsoft Docs](https://docs.microsoft.com/en-us/rest/api/storageservices/lease-blob) 
- Azure CLI 2.0
    - [az storage container lease | Microsoft Docs](https://docs.microsoft.com/en-us/cli/azure/storage/container/lease?view=azure-cli-latest)
    - [az storage blob lease | Microsoft Docs](https://docs.microsoft.com/en-us/cli/azure/storage/blob/lease?view=azure-cli-latest)

```bash:CLI-blobのリース
az storage blob lease --help

Group
    az storage blob lease: Manage storage blob leases.

Commands:
    acquire: Requests a new lease.
    break  : Breaks the lease, if the blob has an active lease.
    change : Changes the lease ID of an active lease.
    release: Releases the lease.
    renew  : Renews the lease.
```
```bash:CLI-containerのリース
az storage container lease --help

Group
    az storage container lease: Manage blob storage container leases.

Commands:
    acquire: Requests a new lease.
    break  : Break the lease, if the container has an active lease.
    change : Change the lease ID of an active lease.
    release: Release the lease.
    renew  : Renews the lease.
```

Azure ポータルで試してみる
====

Azure ポータルでは、「リースの取得」と「解約」が行えます。期限の設定などは行えませんが、ロックをかけるだけならこれで十分です。

![20180210_001.png](https://qiita-image-store.s3.amazonaws.com/0/3812/199d5f48-6cd4-908b-8496-dfc8a8919ba0.png)


CLI で試してみる
====
CLI を使うと、リースの取得と解約のほかに、リースの期間を指定したり、解約せずに更新（renew）してリースを維持できます。

## まず、同じファイル名でアップロードすると、上書きされることを確認する
```bash
# 異なるファイルを用意する
echo "This is a first content." > test-first.txt
echo "This is a newer content." > test-newer.txt
echo "This is a third content." > test-third.txt

# test-overwrittern.txt のアップロードする
az storage blob upload --account-name teststorageaccount --container-name test-container --file ./test-first.txt --name test-overwritten.txt

# test-overwritten.txt をダウンロードする
az storage blob download --account-name teststorageaccount  --container-name test-container --name test-overwritten.txt --file downloaded/test-overwritten.txt

# アップロードしたファイルのままであることが確認できた
cat downloaded/test-overwritten.txt
This is a first content.

# 異なるファイル test-newer.txt を同じファイル名でアップロードし、ダウンロードして確認する
az storage blob upload --account-name teststorageaccount  --container-name test-container --file ./test-newer.txt --name test-overwritten.txt
az storage blob download --account-name teststorageaccount --container-name test-container --name test-overwritten.txt --file downloaded/test-overwritten2.txt

# 上書きされている
cat downloaded/test-overwritten2.txt
This is a newer content.
```

## リースを取得してから、上書きを試みる
```bash
# ファイルをアップロードし、確認する
az storage blob upload --account-name teststorageaccount --container-name test-container --file ./test-first.txt --name test-not-overwritten.txt
az storage blob download --account-name teststorageaccount --container-name test-container --name test-not-overwritten.txt --file downloaded/test-not-overwritten.txt

cat downloaded/test-not-overwritten.txt
This is a first content.

# リースを取得する（期間は無制限を指定する）
az storage blob lease acquire --account-name teststorageaccount --container-name test-container --blob-name test-not-overwritten.txt --lease-duration -1
"1886224a-6373-4c0e-b37b-bad54e1fb63d"

# 上書きしてみるが、できないことが確認できる
az storage blob upload --account-name teststorageaccount --container-name test-container --file ./test-newer.txt --name test-not-overwritten.txt
There is currently a lease on the blob and no lease ID was specified in the request.
... <略> ...
```

## リースIDを指定すると上書きできる

```bash
# リースIDを指定すると、上書きできる
az storage blob upload --account-name teststorageaccount --container-name test-container --file ./test-newer.txt --name test-not-overwritten.txt --lease-id 1886224a-6373-4c0e-b37b-bad54e1fb63d
az storage blob download --account-name teststorageaccount --container-name test-container --name test-not-overwritten.txt --file downloaded/test-not-overwitten2.txt

cat downloaded/test-not-overwitten2.txt
This is a newer content.
```

## リースを開放する
```bash
# リースを取得する
az storage blob lease acquire --account-name teststorageaccount --container-name test-container --blob-name test-not-overwritten.txt --lease-duration -1
"82efeb32-345c-4122-ba48-854903a17d77"

# リースIDを指定してリースを開放することができる
az storage blob lease release --account-name teststorageaccount --container-name test-container --blob-name test-not-overwritten.txt --lease-id 82efeb32-345c-4122-ba48-854903a17d77

# リースを開放すると上書きできるようになる
az storage blob upload --account-name teststorageaccount --container-name test-container --file ./test-third.txt --name test-not-overwritten.txt
az storage blob download --account-name teststorageaccount --container-name test-container --name test-not-overwritten.txt --file downloaded/test-not-overwitten3.txt

cat downloaded/test-not-overwitten3.txt
This is a third content.

# 再度リースを取得することができる
az storage blob lease acquire --account-name teststorageaccount --container-name test-container --blob-name test-not-overwritten.txt --lease-duration -1
"8fb6f633-af1f-44d7-a95d-6ba9bb112a78"
```

### リースの状況を確認する

`az storage blob show ` でリースの状況を確認できます。 `--query` オプションと組み合わせることで、特定の項目のみを得ることができます。

```bash
# リースを取得する
az storage blob lease acquire --account-name test storage account --container-name test-container --blob-name test-not-overwritten.txt --lease-duration -1

# リースの状況を確認する
az storage blob show --account-name teststorageaccount --container-name test-container --name test-not-overwritten.txt --query "properties.lease"
{
  "duration": "infinite",
  "state": "leased",
  "status": "locked"
}
```

### リースの期限を指定してみる

`az storage blob lease acquire` の `--lease-duration` にリースの期限を秒数で指定することができます。また、期限がきれたリースは、 `az storage blob lease renew` で再度取得することができます。

```bash
# 60秒の期限をつけてリースを取得する
az storage blob lease acquire --account-name teststorageaccount --container-name test-container --blob-name test-not-overwritten.txt --lease-duration 60 && date
"ccc2825a-dc64-40a7-b279-1ee01ee90375"
Sat Feb 10 12:29:42 UTC 2018

# リースの状況がリース中であることが確認できる
az storage blob show --account-name teststorageaccount --container-name test-container --name test-not-overwritten.txt --query "properties.lease" && date
{
  "duration": "fixed",
  "state": "leased",
  "status": "locked"
}
Sat Feb 10 12:29:48 UTC 2018

# 60 秒後、リースの期限が切れたことが確認できる
az storage blob show --account-name teststorageaccount --container-name test-container --name test-not-overwritten.txt --query "properties.lease" && date
{
  "duration": null,
  "state": "expired",
  "status": "unlocked"
}
Sat Feb 10 12:30:44 UTC 2018

# リースを更新する
az storage blob lease renew --account-name teststorageaccount --container-name test-container --blob-name test-not-overwritten.txt --lease-id ccc2825a-dc64-40a7-b279-1ee01ee90375 && date
"ccc2825a-dc64-40a7-b279-1ee01ee90375"
Sat Feb 10 12:31:05 UTC 2018

# 再度リースが取得できたこと確認できる
az storage blob show --account-name teststorageaccount --container-name test-container --name test-not-overwritten.txt --query "properties.lease" && date{
  "duration": "fixed",
  "state": "leased",
  "status": "locked"
}
Sat Feb 10 12:31:15 UTC 2018

# 最初に指定した期間が経過後、リースの期限が切れる
az storage blob show --account-name teststorageaccount --container-name test-container --name test-not-overwritten.txt --query "properties.lease" && date
{
  "duration": null,
  "state": "expired",
  "status": "unlocked"
}
Sat Feb 10 12:33:39 UTC 2018
```

## リースを解約する

`az storage blob lease break` を使うと、リースIDなしに解約できるようです。強制的にリースを解除したい場合にのみ利用する想定でしょうか。

```bash
# リースを解除する
az storage blob lease break --account-name teststorageaccount --container-name test-container --blob-name test-not-overwritten.txt
0
```

Epilogue - おわりに
====
上書きしたくない、消したくないファイルに設定しておきたいですね！ポータルからが一番簡単です。（リースの取得と解約のみ）

リースという概念はあまり慣れてないので、ユースケースをもう少し深掘りしてみたいと思いました。