Azure リソースを誤って削除してしまわないためのベストプラクティス

#はじめに
先日、Azureサブスクリプション内の不要なリソースを整理していたら誤って必要なリソースを削除してしまいました。完全なやらかしです。
完全に自分個人のリソースなので迷惑をかけたということはなかったのですが、ヘビーユースしている自身の環境だったので失いたくないデータなどが入っている仮想マシンなどもあり、削除ボタンを押したことの意味に気づいた時は冷や汗ダラダラでした。
クラウドサービスでは環境の作成・削除ができるのはとっても便利ですが、一方きちんと管理しないとスーファミのドラクエでセーブデータが消えた時並みの絶望感を味わうことになると身を持って実感しました。そこでこの反省を機会にAzureリソースをヒューマンエラーで消失しないための方法を整理したいと思います。

#1.リソースの変更or削除のロックを設定する
これが一番容易にシンプルに今すぐにでもできる方法かと思います。
Azureではサブスクリプション、リソースグループ、リソースの３つのレベルで操作に対してロックを設定することができます。ロックの種類はCanNotDelete(削除)とReadOnly(読み取り専用)の２つあり、CanNotDelete(削除)はリソースに変更を加えることはできるが削除はできないというロック、ReadOnly(読み取り専用)は変更すら実施できないというロックです。
間違えてリソース構成を変更することすら防ぎたい場合はReadOnlyを使うべきですが、リソースグループにReadOnlyのロックを設定すると、リソースグループ内に別のリソースをデプロイすることもできなくなるので検証等の環境だとロックすることで面倒な場合もあるかと思います。ロックの設定・解除は、ポータルから容易にできますが、状況にあわせて適切なレベルのロックを設定することが重要だと思います。

![ロック.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192113/73be6661-4e6c-dc73-8446-08f2337ed3b0.png)

※参考
[リソースのロックによる予期せぬ変更の防止]( 
https://docs.microsoft.com/ja-jp/azure/azure-resource-manager/resource-group-lock-resources)

#2.リソースの削除権限を持たないユーザでリソースを管理する
そもそもユーザアカウントに与えるAzure リソースの操作権限を厳密に管理しようという方法です。
普段どんなAzure ユーザでも、自身のユーザアカウントで azureポータルにログインしAzureリソースを操作しているかと思います。Azure上の全てのリソースは、1つのサブスクリプションに所属しています。そしてサブスクリプションは、必ず１つのAzure ADのディレクトリに紐づいています。
Azure AD 上のユーザアカウント（Microsoftアカウントや組織アカウント）に対して任意のスコープ（サブスクリプション、リソースグループ、リソース）でどんな操作が実行できるかという制御を、RBAC(role-based access control)という仕組みで実現できます。なので、例えば検証用のリソースグループと重要なリソースグループといった単位で操作権限を厳密に分けておけば、誤操作を防ぐことも可能です。

※参考
[Azure リソースのロールベースのアクセス制御 (RBAC) の概要](https://docs.microsoft.com/en-us/azure/role-based-access-control/overview)

ロールベースという名称だけあって、どういう操作が可能か（あるいは不可能か）といった権限を定義したロール（役割）をユーザアカウントに割り当てる方式ですが、Azure側が最初から用意しているよくある権限セットとして組み込みロールというものがあります。
ロール自体をカスタムロールとしてユーザ自身で定義することもできますが、組み込みロールをつかうと既に用意されているものを使う分、柔軟性はないものの比較的設定は用意です。所有者（Owner）が最も強い権限を持つロールなのでこれをむやみやたらに使わないだけでも誤操作は減らすことができる気と思います。
1のロックよりは権限設計が必要な分、個人サブスクリプションで実施するにはヘビーな選択肢かと思います。

#3.Azure BluePrintでロックを強制する
Azure BluePrintは、その名のとおりAzureのリソース構成の青写真(=Blue Print)を定義しておく機能です。例えば、ストレージやVMなどのリソースの数量や、パラメータ（SKU, Size, スペック）などの構成を事前にBlue Printとして定義しておき、その定義にそってリソースをデプロイするというフローが可能になります。統制だったリソース管理を必要とする場面で便利な機能かと思います。
そして、Blue Printベースでリソースをデプロイする際には、リソースを容易に削除できないようにロック機構を有効化することができます。

※参考
[Azure Blueprints サービスの概要](https://docs.microsoft.com/ja-jp/azure/governance/blueprints/overview)

BluePrintのロックは、1つめのリソースロックとは別の仕組みで動作しており、2つめの RBAC のNotAction（実行できない操作）を用いて明示的に削除操作権限を持つユーザでない限りリソース削除を実行できないといった挙動のようです。

# 4.Azure Backupでバックアップを構成する
主に VM リソースを対象とした手段ですが、Azure VM にバックアップを構成しておくという対策です。

※参考
[VM の設定から Azure VM をバックアップする](https://docs.microsoft.com/ja-jp/azure/backup/backup-azure-vms-first-look-arm)
 
![バックアップ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192113/e1b7d853-ce9f-bff9-e860-d4cb36d470ed.png)

Azure Backupを設定しておくと、誤操作によるリソース削除という観点では次の２つの意味があります。
・誤操作でバックアップ対象を削除しても直近のバックアップからリソースを復元でき被害を最小化できる
・バックアップデータが保存されるRecovery Service コンテナは、明示的にバックアップデータを削除しない限りリソースを削除できない。

1つ目も重要ですが、特に2つ目が重要です。
仮にリソースグループなど削除した場合も、Recovery Service コンテナだけは、明示的にコンテナのバックアップの設定を解除し、既に保存されているバックアップデータを削除することを事前に完了していなければ、エラーとなり削除できません。
そのため、「リソースグループごと消してしまってVMやディスクも全て消失してしまったけどバックアップだけは削除できずに残っていた！」となり、かなりの確率で誤操作による事故影響を最小化できると思われます。

※参考
[Recovery Services コンテナーを削除する]( https://docs.microsoft.com/ja-jp/azure/backup/backup-azure-delete-vault)

#まとめ
書いていて、1,2,3 はフェールプルーフ、4はフェールセーフで微妙に方針が違う対策だなと気づきました。
2,3はちょっと手間はかかるので個人レベルで実施するなら、1のリソースロックと4のAzure Backupがおすすめです。特に1は料金もないのですぐにでも実施するのが良いと思います。