ユーザーへ Azure VM の起動、停止と接続のみを許可したい

Azure ポータルなどでユーザーがアクセスできるリソースを限定させたい、リソースへの操作を限定させたい場合、[ロールベースのアクセス制御 (RBAC)](https://docs.microsoft.com/ja-jp/azure/role-based-access-control/overview?WT.mc_id=AZ-MVP-5003113) を使用して制御します。 
あらかじめ用意された[組み込みロール](https://docs.microsoft.com/ja-jp/azure/role-based-access-control/built-in-roles?WT.mc_id=AZ-MVP-5003113)で事足りれば良いのですが、それよりさらに制限させたい場合は、やはり[カスタムロール](https://docs.microsoft.com/ja-jp/azure/role-based-access-control/custom-roles?WT.mc_id=AZ-MVP-5003113)を作って、ユーザーにそれを割り当てます。

カスタムロールって面倒くさいなーって思い込んでいましたが、実際にやってみたらそんなことはありませんでした。

# ユーザーへ Azure VM の起動および停止のみを許可する方法
Azure サポートの以下の記事を参考にしました。

[参考：ユーザーへ Azure VM の起動および停止のみを許可する方法 - Japan Azure IaaS Support Blog](https://blogs.technet.microsoft.com/jpaztech/2018/08/15/vm_start_stop_user/)

この記事を要約すると冒頭で書いたとおりですが、具体例として「ユーザーに特定の仮想マシンの起動と停止のみ許可する」手段について書かれています。
![jazug_p4.png](https://qiita-image-store.s3.amazonaws.com/0/230264/deecca75-beae-0099-c024-ca71da4abd0b.png)

この具体例のとおりにアクセス制限させるためには、

- 以下の操作が Action プロパティに含むロールをユーザーに割り当てる
 - Microsoft.Compute/virtualMachines/read
 - Microsoft.Compute/virtualMachines/deallocate/action
 - Microsoft.Compute/virtualMachines/start/action
- これらのプロパティが含む組み込み (既定の) ロールは
 - 所有者 (Owner)
 - 共同作成者 (Contributor)
 - 仮想マシン共同作成者 (Virtual Machine Contributor)
 - DevTest Labs ユーザー (DevTest Labs User)
- ユーザーに組み込みロールを割り当てるなら、限定的な「DevTest Labs ユーザー」が最適
- 許可する操作のみを明示的に限定したいなら、「カスタムロール」を作成 → ユーザーにそれを割り当てる

ちょうど情シスから「仮想マシンの起動、停止、接続のみ許可できるなら、システムの担当者にも Azure ポータルにアクセスさせても良いんだけど...今それないからよろしくねー」という話があり、私もいつまでも付き合っていられないので、以下のようなカスタムロールを作ることにしました。

![jazug_p6.png](https://qiita-image-store.s3.amazonaws.com/0/230264/ea6187b5-5d3f-5bf8-b633-fc3506ab09c5.png)

# 1.カスタムロール定義 (json) を作成
カスタムロールを作るためには、定義ファイルを用意する必要があります。書式は以下のとおり。

```customroles.json
{
  "Name": "カスタムロールの名前",
  "IsCustom": true,
  "Description": "カスタムロールの説明",
  "Actions": [
    "COMMENT:このロールで実行できる操作を指定"
  ],
  "NotActions": [
    "COMMENT:実行できる操作の中 (Actions) から除外する操作を指定"
  ],
  "DataActions":  [
    "COMMENT:対象のオブジェクト内のデータに対して、このロールで実行できるデータ操作を指定 ※プレビュー"
  ],
  "NotDataActions": [ 
    "COMMENT:実行できるデータ操作の中 (DataActions) から除外するデータ操作を指定 ※プレビュー"
  ],
  "AssignableScopes": [
    "COMMENT:このロールを割り当て可能なスコープ (サブスクリプション, リソースグループ, リソース) を指定"
  ]
}
```

リソースに対する操作は、以下の記事から探し出します。
巨大なページなので、ページ内検索を駆使してやりたいことを探し出します。
ピンとこない説明に苦戦、負けそうです...(@_@)
※もっと良い方法あるかな??

[参考：Azure Resource Manager のリソース プロバイダー操作](https://docs.microsoft.com/ja-jp/azure/role-based-access-control/resource-provider-operations?WT.mc_id=AZ-MVP-5003113)

そんなこんなで私が作ってみたカスタムロールの定義は以下のとおり。

``` AzureVMStartStopConnect.json
{
  "Name": "Azure VM Start/Stop/Connect",
  "IsCustom": true,
  "Description": "Azure 仮想マシンの起動、停止、接続のみを許可するロール",
  "Actions": [
     "Microsoft.Compute/virtualMachines/read"
    ,"Microsoft.Compute/virtualMachines/deallocate/action"
    ,"Microsoft.Compute/virtualMachines/restart/action"
    ,"Microsoft.Compute/virtualMachines/start/action"
    ,"Microsoft.Network/networkInterfaces/*/read"
    ,"Microsoft.Network/networkInterfaces/read"
    ,"Microsoft.Resources/subscriptions/resourceGroups/read"
    ,"Microsoft.Resources/subscriptions/resourceGroups/resources/read"
    ,"Microsoft.ClassicCompute/virtualMachines/read"
    ,"Microsoft.ClassicCompute/VirtualMachines/start/action"
    ,"Microsoft.ClassicCompute/virtualMachines/shutdown/action"
    ,"Microsoft.ClassicCompute/virtualMachines/restart/action"
    ,"Microsoft.ClassicCompute/virtualMachines/downloadRemoteDesktopConnectionFile/action"
    ,"Microsoft.ClassicCompute/virtualMachines/operationStatuses/read"
  ],
"AssignableScopes": [
     "/subscriptions/<サブスクリプション ID>"
  ]
}
```

クラシック仮想マシンはやりたい操作の Action を探し出すのはとてもラクでしたが、ARM 仮想マシンはやりたい操作に関連するリソースを考えながら書いていきました。あとは、やりたい操作が実現できている組み込みロールを参考にしながら書きました。(今回は「DevTest Labs ユーザー」ロールを参考にしました。)

# 2.サブスクリプションにカスタムロール定義を登録
PowerShell で作成したカスタムロール定義を登録します。

```
# ログイン
PS C:\> Login-AzureRmAccount

# サブスクリプションを選択
PS C:\> Select-AzureRmSubscription -Subscription <サブスクリプション ID>

# カスタムロールを登録
PS C:\> New-AzureRmRoleDefinition -InputFile <カスタムロール定義ファイルパス>
```

# 3.リソースのアクセス制御にユーザーを登録
あとは、特定のリソースのアクセス制御に、登録したカスタムロールを割り当てたユーザーを登録します。

役割に登録したカスタムロール (Azure VM Start/Stop/Connect) が登録されていることを確認。

![jazug_p11.png](https://qiita-image-store.s3.amazonaws.com/0/230264/5907f871-2cf5-02a1-c0de-08af30ce9ea3.png)

仮想マシンのアクセス制御に、登録したカスタムロールを割り当てたユーザーを登録します。

![jazug_p11_2.png](https://qiita-image-store.s3.amazonaws.com/0/230264/2a6daf1d-6ca1-6b34-476d-205723d5891b.png)

# 登録したカスタムロールを書き換えたい
はじめから希望どおりのものが作れるわけでもなく、トライ&エラーを何度も繰り返しました。
カスタムロールを登録し直す場合は、ユーザーに割り当てたロールを解除→再割り当てしたり、登録したカスタムロールを削除→再登録したりすると、それらの設定がうまく反映されない (反映がとても遅い) 場合があります。

最も良いやり方は、リソースのアクセス制御のカスタムロールを割り当てたユーザーはそのままに、PowerShell で、以下のように「ロールを取得」、「ロールのプロパティを編集」、「ロールを更新」という手順を行うと良いと思います。

- Get-AzureRmRoleDefinition
- ロールのプロパティを編集 ※Actions や NotActions などのデータ型は List[string]
- Set-AzureRmRoleDefinition

![jazug_p12.png](https://qiita-image-store.s3.amazonaws.com/0/230264/674f31fd-9de3-cf26-03dd-37d203f55174.png)

# 参考文献
- [ユーザーへ Azure VM の起動および停止のみを許可する方法 - Japan Azure IaaS Support Blog](https://blogs.technet.microsoft.com/jpaztech/2018/08/15/vm_start_stop_user/)
- [ロールベースのアクセス制御 (RBAC) の設定 – カスタムロールの使用 - Japan Azure IaaS Support Blog](https://blogs.technet.microsoft.com/jpaztech/2016/10/12/rbac-custom-role/)
- [Azure の組み込みロール](https://docs.microsoft.com/ja-jp/azure/role-based-access-control/built-in-roles?WT.mc_id=AZ-MVP-5003113)
- [Azure のカスタム ロール](https://docs.microsoft.com/ja-jp/azure/role-based-access-control/custom-roles?WT.mc_id=AZ-MVP-5003113)
- [ロール定義について](https://docs.microsoft.com/ja-jp/azure/role-based-access-control/role-definitions?WT.mc_id=AZ-MVP-5003113)
- [Azure Resource Manager のリソース プロバイダー操作](https://docs.microsoft.com/ja-jp/azure/role-based-access-control/resource-provider-operations?WT.mc_id=AZ-MVP-5003113)