Azureのサブスクリプションやリソースグループや権限管理の最低限の考慮事項

Azureを扱う際、FunctionsとかSQLDatabaseのような、いわゆる"リソース"よりも上位の概念が存在します。
リソースグループ(Resource Group)、サブスクリプション(Subscription)、管理グループ(Management Group)がそれに該当します。
また、これらと同時期に検討されるのが権限管理です。
今回は、これらをどう分割したら良い感じの環境になるのかを考えてみたいと思います。


環境の分割方法にビシッとした正解はありません。正直なところ、みなさんが使いやすく適切に管理できれば良いと思います。
ですが、後から変更するのが面倒であることも事実です。考慮事項として頭の片隅に置いていただけますと幸いです。

# 結論

1. 支払い部門や使用用途別にサブスクリプションは分割する
2. サブシステム単位や環境の利用者を意識してリソースグループは分割する
3. Azureの利用範囲を意識して権限管理のグループを分割する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439826/657d2ea4-9c31-1284-cb1a-1c5f1536ddcc.png)



# 分割を意識しないと何が起こるのか
フンワリと動作確認しているレベルでしたら、特に何も起こらないと思います。全部ごった煮にしてもおおむね問題は起こりません。
私も、PoCやハンズオンで皆様に環境準備いただく際は、例えばリソースグループの説明は「一括削除できる単位だと思ってください」くらいにしか説明しません。

ある程度の人数で、ある程度のリソースを真面目に操作するとなった場合（要するに、きちんと作り始めたら）、発生する事象として以下のようなものがあげられます。

- 誰がどの財布で支払うのかが不明瞭になってくる
- リソースが枯渇する
- 権限管理があいまいになってくる

## 誰がどの財布で支払うのかが不明瞭になってくる
オンプレでも同じだと思います。サーバーを調達するということは、どこの部門がどの費目に紐付けて支払うのか確定する必要があるのではないでしょうか？
クラウドは固定費ではありませんが、それでも本番環境はサービスを運用する部門ごとの費用になるでしょうし、そのための開発環境は開発のプロジェクトに紐付けた費用として支払う必要があったりするかと思います。
よって、部門や費目は分割する必要があります。

## リソースが枯渇する
リソースには、さまざまな上限値が存在します。その上限値を決める材料の１つが、サブスクリプションです。
よって、いろいろなサービスを１サブスクリプションに混在させてしまうと、リソースの上限値が早く訪れる可能性があります。

## 権限管理があいまいになってくる
権限管理、面倒ですよね？私は正直きらいです。何が面倒かと言うと、権限付与の"申請方法"は明記されていることが多いのですが、勝手にはく奪する方法について明確になっていることが少ないのが面倒です。
そしてそれを最初から最後まで自分ひとりで運用することは無いため、引き継いでも引き継がれても不明瞭極まりない権限管理状況になります（私の場合です）。
そして適当にはく奪したら"使えなくなった"と怒られるし、監査しないとうるさいし、増えるばかりの権限の監査なんてミス無くできないわけです（私の場合はできません）。

それでは、どんな考慮事項があるのか、順を追って考えていきたいと思います。

# 部門と支払い単位を明確にする
これは会社の事業規模等にも関わってきますので正解は無いのですが、まずはAzureをご利用になられる部門と支払いの単位を明確にしていただくと良いかと思います。

この単位を意識したものが、Azureでは"管理グループ(ManagementGroup)"と"サブスクリプション(Subscription)"です。
管理グループに関する詳細な説明はこちらの[Azure 管理グループでリソースを整理する](https://docs.microsoft.com/ja-jp/azure/governance/management-groups/overview)からご確認ください。
## 管理グループ
管理グループは端的に言えば部門です。そのサービスを担当する部門、今回稟議書をまわした部門、運用を担当する例えばIT部門、会社によってとらえ方は様々だと思いますが、そういう部門です。
ここで意識した方が良いのは、このクラウド環境を構築したあと、面倒見ていかなければならなくて、面倒を見るためには権限というものが必要で、権限は付与したりはく奪したりしないといけないので面倒だということです。
よって、管理グループは会社に既存のルールが存在すればルールに従いましょう。何もなければ権限管理とサービスの運用をする部門に任せましょう。
## サブスクリプション
サブスクリプションは端的に言えば支払いのグループです。
マイクロソフトがお金を支払ってほしいと思っているリソースはすべて、どれかのサブスクリプションに紐付きます。
利用者目線で言いますと、これは料金を支払う際の最小単位となります。
先ほども少し記載しましたが、例えば本番環境のコストは継続的なコストです。開発環境のコストは、各プロジェクト期間にあわせたコストです。
ウォーターフォールだろうとアジャイルだろうと、プロジェクトである以上、開始と終了が存在しますし、期間ごとに消費される費用として原価計上すべきではないでしょうか。
余談ですが、利用月と支払月には差が生じます。プロジェクトの検収期間等ご配慮ください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439826/fa8d5cdb-331f-07b4-8c7b-fabb416e2428.png)

## 支払いに関するまとめ
支払いを意識した際に、"サブスクリプション"は支払いを行う部門や、その費目を意識して分割した方が良いと思います。例えば本番環境は部門の費用としてチャージ、開発環境はプロジェクト予算として計上しチャージするというような分割です。
"管理グループ"は会社の事業規模等によって分割するしないは様々であろうと理解できたかと思います。(むしろ権限管理と運用を意識して分割有無を検討した方が良い)


# リソースの上限値
Azure上には、多くのリソースを作成することが可能です。しかしながら、無限ではありません。念のために設けられているソフトなリミットと、超過できないハードなリミットが存在します。
ソフトなリミットは申請すれば上限値を上げることができますが、ハードなリミットは超過できませんので注意が必要です。

## 上限値を考える最上位の概念はサブスクリプション
Azureのリソース上限は、こちらの『[Azure サブスクリプションとサービスの制限、クォータ、制約](https://docs.microsoft.com/ja-jp/azure/azure-resource-manager/management/azure-subscription-service-limits)』で確認することができます。
タイトルからもわかる通り、Azureで利用可能なリソースの上限値はサブスクリプション単位から考えます。
例えばこちら
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439826/ed9c6c76-e774-0f6d-5044-56a755e91cb7.png)
1. 1サブスクリプションあたり、2,000ロールまで割り当て可(ロールについては後述)
2. 1サブスクリプションあたり、980リソースグループまで
3. 1リソースグループあたり、100AppServicePlanまで(Premium v2)

この例でいえば、AppServicePlanは1サブスクリプションあたり、98,000個までしか(?)起動できません。会社全体を1サブスクリプションで管理すると超過しそうですが(本当か？？)、各システムが各環境(本番・開発等)ごとにサブスクリプションを準備していれば、超過のリスクは低減しそうです。

## リソースの上限値に関するまとめ
"サブスクリプション"という単位を最初に意識したほうが良い

# アクセス制御
Azureの環境は、誰でもどこでも入れるわけではありません。
権限を付与された人が、付与された範囲に限って付与された行動をとることが可能になっています。
この権限付与のことをRBAC(ロールベースアクセス制御)と言います。

## 権限管理は"どこに対して""何ができる"を決めることから始まる
権限の管理の方式は単純です(シンプルでなければ管理できない)。
まず管理対象となる"どこに対して"を決めます。これを"スコープ"と呼びます。
次に権限種別となる"何ができる"を決めます。これを"ロール"と呼びます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439826/31b0bb89-adbc-8480-634f-f60097c2af77.png)
スコープに対してロールを割り当てることを"ロールの割り当て"と呼びます。
前述の"1. 1サブスクリプションあたり、2,000ロールまで割り当て可(ロールについては後述)"というのは、この割り当て数の上限をさします。
ロールは個人指定もできますが、通常は"グループ"というものを使います。WindowsにもAdministratorsグループみたいなのがあったかと思います。Linuxにもあるので理解できるかと思います。


## 権限は上位スコープから引き継がれる
付与された権限は、上位スコープから引き継がれます。例えばサブスクリプション単位で読み取り権限を付与されたユーザーは、リソースも読み取ることができます。(言葉として変な感じもしますがそういうことです。)
詳しくはこちらの[Azure リソースのロールベースのアクセス制御 (RBAC) の概要](https://docs.microsoft.com/ja-jp/azure/role-based-access-control/overview)をご確認ください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439826/c64ae847-b2d8-31fe-f014-eb187e1d7e46.png)

## ロールの割り当て作業の概要
１．マネジメントグループ配下に、グループや個人を作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439826/6d292ede-db5e-bb2d-907c-b174aa3f6a27.png)
Azureポータル上ですと、グループの作成はここになります。"グループ"と検索してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439826/23717745-4ac0-2099-c41d-1a2b9d03d8d0.png)

２．サブスクリプション、リソースグループ、リソースに対してロールを割り当てる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439826/fb0b3b73-b617-2ed2-4507-b0e12ed6f018.png)
Azureポータル上ですと、割り当てしたいサブスクリプション等(スコープ)を選択し、"アクセス制御(IAM)"を選択、"追加"の"ロールの割り当ての追加"を選択します。
すると、ポータル右側に追加用画面が出てきますので、割り当てたいロールと割り当てたいグループや個人を選択し、"保存"ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439826/6fd34222-3457-22e1-ac6f-448339f4dc18.png)

## ロールの割り当て数の数え方
例えば、１つのサブスクリプションに２つのリソースグループだけが存在するとします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439826/7524a358-7fd5-320b-0a2b-f5e3d89e3902.png)
上記の例ですと、ロール割り当ては7消費します。
例えばグループDのReader権限は不要ですが(Contributor権限でカバーできる)、指定している以上消費します。
権限が重複指定できるため、「良い感じにしてよ」と思う気持ちは理解できます。
しかし一時的な権限付与、はく奪等も柔軟に対応できますし、利便性は高いです。

グループCをサブスクリプションに対してContributor権限にして(+1)、各リソースグループに対して付与したロール割り当てを解除(-2)することでロール割り当ては6になります。
同じことを指定するなら、上位から指定すれば割り当て数の消費は少なくて済みます。

## 権限関係は何を基準に作るか
ロール割り当ての基本的な考え方は、「Azure上で"誰が""何を"できるべきか」です。
よって、まずはAzure上での作業割り当てや必要な権限を基準にグループを作成してください。
次に、その基準に沿ってロール割り当てを実施してください。
例えば、"本番環境を見ることができるグループ"を作成して、本番のサブスクリプションの"アクセス権(IAM)"でReader権限を与えてください。

このグループの作り方を失敗すると、セキュアではなくなりますし、ロール割り当て数も膨大になりますし、管理できなくなります。
例えば、会社単位とか、部署単位とか、組織のルールを基準にグループを作成すると管理が大変になります。
作ってみるとわかりますが、"会社や組織の単位"と"Azureのどこをどれだけ触れるべきか"の間には、何も相関関係がありません。

## ユーザーについて考えておきたいこと
本当に環境に入らなければならないのは誰なのかをハッキリさせたほうが幸せになれると思います。
ユーザーレベルでも数を増やさない仕掛けと、権限はく奪しやすい仕掛けが大切です。
例えば

- CI/CDの仕組みを構築し、デプロイのためにユーザーを入れない
- 障害復旧を自動化する仕組みを構築し、復旧のためにユーザーを入れない(最低限にとどめる)
- 運用可視化に必要な仕組みを構築し、監視のためにユーザーを入れない(最低限にとどめる)


## アクセス制御に関するまとめ
Azure上のアクセス権限を制御するための"RBAC"、これを正しく扱うためには"Azure上のアクセス権限"の話題であるということを意識する
そして、グループもユーザーも数を極力を減らす

# まとめ
１番最初に結論を記載しましたので省略。
こちらも最初に記載しましたが、正解はありませんので、考慮事項の１つとしてご確認いただけたらと思います。