[Azure] PowerShellでカスタムロールを作成してみる

# ロールベース アクセス制御(RBAC)によるアクセス制御

ロールベース アクセス制御(RBAC, Role-Based Access Control)とは、Azureにおいてリソースごとのアクセス制御を行う仕組みのことです。

各ユーザ/グループに対して、ロール(Role)を付与することでアクセス制御を行います。

ロールは現在(2017/08/28時点で)60個の組み込みロールが提供されていますが、各ユーザの用途に応じたカスタムロールを作成することも可能です。カスタムロールの作成機能はAzureポータルでは提供されておらず、PoweShell、CLI、またはAPIで作成することが可能です。

# 組み込みロールの一覧

少し長くなりますが、現在(2017/08/28)時点の組み込みロール一覧を全て掲載しておきます。クラシックリソースに関するものは除いています。

一覧は [こちらのドキュメント:Azure ロールベースのアクセス制御の組み込みロール](https://docs.microsoft.com/ja-jp/azure/active-directory/role-based-access-built-in-roles) にあるのですが、更新が頻繁にあるせいか、Azureポータルで確認できる最新の一覧とは一致していません。

また、ポータルではロール名が日本語で表示されていますが、PowerShellでは英語の方を使う必要があります。まだ翻訳に表記揺れが多く、ソート順も変わってしまうので少々紛らわしい状態になっています。

|ロール名(en)                | ロール名(jp) | 説明    |
|:------------------------|:------------------|:-----------------------------------------|
|Owner | 所有者 | 全てのリソースに対して、全ての操作が可能。<br>AWSの'AdministratorAccess'に相当 |
|Contributor | 共同作成者 | アクセス権設定以外の全ての操作が可能。<br>AWSの'PowerUserAccess'に相当 |
|Reader | 閲覧者 | 全てのリソースの閲覧が可能。<br>AWSの'ReadOnlyAccess'に相当 |
|User Access Administrator | ユーザー アクセス管理者 | ユーザアクセス権の作成と管理。<br>AWSの'IAMFullAccess'に相当 |
|API Management Service Contributor | API Managementサービスの共同作成者  |  |
|API Management Service Operator Role | API Managementサービスのオペレータ |  |
|API Management Service Reader Role | API Managementサービス<font color="Red">の閲覧者</font> | ポータルでは "API Managementサービスの<font color="Red">リーダーロール</font>" となっていて紛らわしいですが、"Leader"ではなく"Reader"です |
|Application Insights Component Contributor | Application Insights コンポーネント共同作成者 |  |
|Application Insights Snapshot Debugger | Application Insights スナップショット デバッガー |  |
|Automation Operator | Automation オペレータ | Automationジョブ、スケジュールの参照と実行 |
|Automation Job Operator | Automation ジョブ オペレータ | Automationジョブの参照と実行 |
|Automation Runbook Operator | Automation Runbook オペレータ | Automation Runbookの参照 <font color="Red">※名前はオペレータだが実行権限が無い</font> |
|Backup Contributor | バックアップ共同作成者 |  |
|Backup Operator | バックアップオペレータ |  |
|Backup Reader | バックアップ<font color="Red">閲覧者</font> | ポータルでは "バックアップ <font color="Red">リーダー</font>" |
|Billing Reader | 課金データ閲覧者 |  |
|BizTalk Contributor | BizTalk 共同作成者 |  |
|CDN Endpoint Contributor | CDNエンドポイントの共同作成者 |  |
|CDN Endpoint Reader | CDNエンドポイント<font color="Red">の閲覧者</font> | ポータルでは "CDNエンドポイント<font color="Red">リーダー</font>" |
|CDN Profile Contributor | CDNプロファイルの共同作成者 |  |
|CDN Profile Reader | CDNプロファイル<font color="Red">の閲覧者</font> | ポータルでは "CDNプロファイル<font color="Red">リーダー</font>" |
|ClearDB MySQL DB Contributor | ClearDB MySQL DB 共同作成者 | ClearDB管理者(Azure Database for MySQLは未対応) |
|Data Factory Contributor | Data Factory 共同作成者 |  |
|Data Lake Analytics Developer |Data Lake Analytics の開発者  |  |
|DevTest Labs User | DevTest Labs利用者 |  |
|DNS Zone Contributor | DNSゾーンの共同作成者 |  |
|DocumentDB Account Contributor | DocumentDB アカウント共同作成者 |  |
|Intelligent Systems Account Contributor | インテリジェント システム アカウント共同作成者 |  |
|Key Vault Contributor | Key Vault の共同作成者 |  |
|Log Analytics Contributor |Log Analytics 共同作成者  |  |
|Log Analytics Reader | Log Analytics 閲覧者 |  |
|Logic App Contributor | ロジックアプリの共同作成者 |  |
|Logic App Operator | ロジックアプリのオペレータ |  |
|Monitoring Contributor | <font color="Red">監視サービスの共同作成者</font> | ポータルでは"<font color="Red">共同作成者の監視</font>"になっており、誤訳と思います |
|Monitoring Reader | <font color="Red">監視サービスの閲覧者</font> | ポータルでは"<font color="Red">閲覧者の監視</font>"になっており、誤訳と思います |
|Network Contributor | ネットワーク共同作成者 |  |
|New Relic APM Account Contributor | New Relic APM アカウント共同作成者 |  |
|Redis Cache Contributor | Redis Cache 共同作成者 |  |
|Scheduler Job Collections Contributor | スケジューラ ジョブ コレクション共同作成者 |  |
|Search Service Contributor | Search サービス共同作成者 |  |
|Security Manager | セキュリティ マネージャ | セキュリティ コンポーネントおよびセキュリティ ポリシーの管理 |
|Security Admin | セキュリティ 管理者 | セキュリティ コンポーネントおよびセキュリティ ポリシーの参照と、仮想マシン(クラシック)の管理 <font color="Red">※古いロール</font> |
|Security Reader | セキュリティ 閲覧者 | セキュリティ コンポーネントおよびセキュリティ ポリシーの参照 |
|Site Recovery Contributor | Site Recovery共同作成者  |  |
|Site Recovery Operator | Site Recoveryオペレータ  |  |
|Site Recovery Reader | Site Recovery閲覧者  |  |
|SQL Server Contributor | SQL Server 共同作成者 |  |
|SQL DB Contributor | SQL DB 共同作成者 |  |
|SQL Security Manager | SQLセキュリティ管理者 |  |
|Storage Account Contributor | ストレージ アカウント共同作成者 |  |
|Storage Account Key Operator Service Role | ストレージ アカウント キー オペレーターのサービス ロール |  |
|Support Request Contributor | サポート リクエスト共同作成者 |  |
|Traffic Manager Contributor | Traffic Manager の共同作成者 |  |
|Virtual Machine Contributor | 仮想マシン共同作成者 | 仮想マシンの作成と管理 |
|Website Contributor |Web サイト共同作成者  | WebAppsの作成と管理(App Service Planは管理できない) |
|Web Plan Contributor | Web プラン共同作成者 | App Service Planの作成と管理 |

# 各ロールの権限を見るには

ポータルでも参照可能ですが、リソースが多く一覧性が悪いのでここではPoweShellで確認します。

<b>`Get-AzureRmRoleDefinition '<ロール名(en)>'`</b>

```powershell
> Get-AzureRmRoleDefinition 'SQL DB Contributor'

Name             : SQL DB Contributor
Id               : 9b7fa17d-e63e-47b0-bb0a-15c516ac86ec
IsCustom         : False
Description      : Lets you manage SQL databases, but not access to them. Also, you can't manage their security-related policies or their parent SQL servers.
Actions          : {Microsoft.Authorization/*/read, Microsoft.Insights/alertRules/*, Microsoft.ResourceHealth/availabilityStatuses/read, Microsoft.Resources/deployments/*...}
NotActions       : {Microsoft.Sql/servers/databases/auditingPolicies/*, Microsoft.Sql/servers/databases/auditingSettings/*, Microsoft.Sql/servers/databases/auditRecords/read, Microsoft.Sql/servers/databases/connectionPolicies/*...
                   }
AssignableScopes : {/}
```

Actions, NotActions(設定されているものがあれば)は長すぎて省略されているので、詳細をそれぞれ確認します。

```powershell
> (Get-AzureRmRoleDefinition 'SQL DB Contributor').Actions
Microsoft.Authorization/*/read
Microsoft.Insights/alertRules/*
Microsoft.ResourceHealth/availabilityStatuses/read
Microsoft.Resources/deployments/*
Microsoft.Resources/subscriptions/resourceGroups/read
Microsoft.Sql/servers/databases/*
Microsoft.Sql/servers/read
Microsoft.Support/*
Microsoft.Sql/locations/*/read
```

```powershell
> (Get-AzureRmRoleDefinition 'SQL DB Contributor').NotActions
Microsoft.Sql/servers/databases/auditingPolicies/*
Microsoft.Sql/servers/databases/auditingSettings/*
Microsoft.Sql/servers/databases/auditRecords/read
Microsoft.Sql/servers/databases/connectionPolicies/*
Microsoft.Sql/servers/databases/dataMaskingPolicies/*
Microsoft.Sql/servers/databases/securityAlertPolicies/*
Microsoft.Sql/servers/databases/securityMetrics/*
```

SQL DB Contributorがデータベースの管理権限を持ち、セキュリティ関連ポリシーの管理を禁止されていることが確認できます。

# PowerShellによるカスタムロールの作成

ここまで長かったですが、やっと本題です。組み込みロールに無い権限を持つカスタムロールをPowerShellで作成してみます。

作成の流れは[Azure PowerShell を使用したロールベースのアクセス制御の管理](https://docs.microsoft.com/ja-jp/azure/active-directory/role-based-access-control-manage-access-powershell)に従っています。

今回は例として、"仮想マシンのオペレータ"ロールを作成してみます。

- 仮想マシン共同作成者(Virtual Machine Contributor)と同じリソースを参照可能
- 変更系は仮想マシンの開始・停止・再起動のみ可能で、それ以外の操作（削除など）は不可能

## 元のロールを確認し、参照権限を作成

Virtual Machine Contributorの権限を元に、参照権限を作成します。

```powershell
> (Get-AzureRmRoleDefinition 'Virtual Machine Contributor').Actions
Microsoft.Authorization/*/read
Microsoft.Compute/availabilitySets/*
Microsoft.Compute/locations/*
Microsoft.Compute/virtualMachines/*
Microsoft.Compute/virtualMachineScaleSets/*
Microsoft.DevTestLab/schedules/*
Microsoft.Insights/alertRules/*
Microsoft.Network/applicationGateways/backendAddressPools/join/action
Microsoft.Network/loadBalancers/backendAddressPools/join/action
Microsoft.Network/loadBalancers/inboundNatPools/join/action
Microsoft.Network/loadBalancers/inboundNatRules/join/action
Microsoft.Network/loadBalancers/read
Microsoft.Network/loadBalancers/probes/join/action
Microsoft.Network/locations/*
Microsoft.Network/networkInterfaces/*
Microsoft.Network/networkSecurityGroups/join/action
Microsoft.Network/networkSecurityGroups/read
Microsoft.Network/publicIPAddresses/join/action
Microsoft.Network/publicIPAddresses/read
Microsoft.Network/virtualNetworks/read
Microsoft.Network/virtualNetworks/subnets/join/action
Microsoft.RecoveryServices/locations/*
Microsoft.RecoveryServices/Vaults/backupFabrics/protectionContainers/protectedItems/*/read
Microsoft.RecoveryServices/Vaults/backupFabrics/protectionContainers/protectedItems/read
Microsoft.RecoveryServices/Vaults/backupFabrics/protectionContainers/protectedItems/write
Microsoft.RecoveryServices/Vaults/backupPolicies/read
Microsoft.RecoveryServices/Vaults/backupPolicies/write
Microsoft.RecoveryServices/Vaults/read
Microsoft.RecoveryServices/Vaults/usages/read
Microsoft.RecoveryServices/Vaults/write
Microsoft.ResourceHealth/availabilityStatuses/read
Microsoft.Resources/deployments/*
Microsoft.Resources/subscriptions/resourceGroups/read
Microsoft.Storage/storageAccounts/listKeys/action
Microsoft.Storage/storageAccounts/read
Microsoft.Support/*
```

ここから変更権限を取り除きます。write権限を削除し、ワイルドカード(*)をreadに変更したものが以下になります。 [この後の手順](https://docs.microsoft.com/ja-jp/azure/active-directory/role-based-access-control-manage-access-powershell)の準備として"$role.Actions.Add"を付与しています。

```powershell
$role.Actions.Add("Microsoft.Authorization/*/read")
$role.Actions.Add("Microsoft.Compute/availabilitySets/read")
$role.Actions.Add("Microsoft.Compute/virtualMachines/read")
$role.Actions.Add("Microsoft.Compute/virtualMachineScaleSets/read")
$role.Actions.Add("Microsoft.DevTestLab/schedules/read")
$role.Actions.Add("Microsoft.Insights/alertRules/read")
$role.Actions.Add("Microsoft.Network/loadBalancers/read")
$role.Actions.Add("Microsoft.Network/networkInterfaces/read")
$role.Actions.Add("Microsoft.Network/networkSecurityGroups/read")
$role.Actions.Add("Microsoft.Network/publicIPAddresses/read")
$role.Actions.Add("Microsoft.Network/virtualNetworks/read")
$role.Actions.Add("Microsoft.RecoveryServices/Vaults/backupFabrics/protectionContainers/protectedItems/*/read")
$role.Actions.Add("Microsoft.RecoveryServices/Vaults/backupFabrics/protectionContainers/protectedItems/read")
$role.Actions.Add("Microsoft.RecoveryServices/Vaults/backupPolicies/read")
$role.Actions.Add("Microsoft.RecoveryServices/Vaults/read")
$role.Actions.Add("Microsoft.RecoveryServices/Vaults/usages/read")
$role.Actions.Add("Microsoft.ResourceHealth/availabilityStatuses/read")
$role.Actions.Add("Microsoft.Resources/deployments/read")
$role.Actions.Add("Microsoft.Resources/subscriptions/resourceGroups/read")
$role.Actions.Add("Microsoft.Storage/storageAccounts/read")
$role.Actions.Add("Microsoft.Storage/storageAccounts/listKeys/action")
```

## 変更権限を追加

[Azure Resource Manager のリソース プロバイダー操作](https://docs.microsoft.com/ja-jp/azure/active-directory/role-based-access-control-resource-provider-operations)を確認し、仮想マシンの開始・停止・再起動の権限を追加します。

```powershell
$role.Actions.Add("Microsoft.Compute/virtualMachines/start/action") # 開始
$role.Actions.Add("Microsoft.Compute/virtualMachines/powerOff/action") # 停止
$role.Actions.Add("Microsoft.Compute/virtualMachines/restart/action") # 再起動
```

## スクリプトの作成と付与

上記で取得した権限から、ロール作成のシェル全体を作成します。

```powershell:test.ps1
$role = Get-AzureRmRoleDefinition 'Virtual Machine Contributor' # 元のロール名
$role.Id = $null
$role.Name = "Virtual Machine Operator" # 新しいロール名
$role.Description = "仮想マシンの閲覧と、開始/停止/再起動のみ可能なロール" # ロールの説明
$role.Actions.Clear()

# 既存のロールから、参照権限を抽出したもの
$role.Actions.Add("Microsoft.Authorization/*/read")
$role.Actions.Add("Microsoft.Compute/availabilitySets/read")
$role.Actions.Add("Microsoft.Compute/virtualMachines/read")
$role.Actions.Add("Microsoft.Compute/virtualMachineScaleSets/read")
$role.Actions.Add("Microsoft.DevTestLab/schedules/read")
$role.Actions.Add("Microsoft.Insights/alertRules/read")
$role.Actions.Add("Microsoft.Network/loadBalancers/read")
$role.Actions.Add("Microsoft.Network/networkInterfaces/read")
$role.Actions.Add("Microsoft.Network/networkSecurityGroups/read")
$role.Actions.Add("Microsoft.Network/publicIPAddresses/read")
$role.Actions.Add("Microsoft.Network/virtualNetworks/read")
$role.Actions.Add("Microsoft.RecoveryServices/Vaults/backupFabrics/protectionContainers/protectedItems/*/read")
$role.Actions.Add("Microsoft.RecoveryServices/Vaults/backupFabrics/protectionContainers/protectedItems/read")
$role.Actions.Add("Microsoft.RecoveryServices/Vaults/backupPolicies/read")
$role.Actions.Add("Microsoft.RecoveryServices/Vaults/read")
$role.Actions.Add("Microsoft.RecoveryServices/Vaults/usages/read")
$role.Actions.Add("Microsoft.ResourceHealth/availabilityStatuses/read")
$role.Actions.Add("Microsoft.Resources/deployments/read")
$role.Actions.Add("Microsoft.Resources/subscriptions/resourceGroups/read")
$role.Actions.Add("Microsoft.Storage/storageAccounts/read")
$role.Actions.Add("Microsoft.Storage/storageAccounts/listKeys/action")

# 開始/停止/再起動の権限を追加
$role.Actions.Add("Microsoft.Compute/virtualMachines/start/action")
$role.Actions.Add("Microsoft.Compute/virtualMachines/powerOff/action")
$role.Actions.Add("Microsoft.Compute/virtualMachines/restart/action")

$role.AssignableScopes.Clear()
$role.AssignableScopes.Add("/subscriptions/<対象のサブスクリプションID>")
New-AzureRmRoleDefinition -Role $role
```

このスクリプトを実行すれば"Virtual Machine Operator"カスタムロールが作成できます。

## 権限付与と動作確認

権限付与はAzureポータルから実行できます。

サブスクリプション → アクセス制御(IAM) → メニュー内の「役割」から付与します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/172826/855608bd-ea30-33cd-057e-7aad56b6fac4.png)

権限付与後そのユーザでログインすれば、仮想マシンの参照と開始/停止/再起動が可能であることが確認できます。

権限の無い操作をするとエラーになることが確認できます。下記は削除操作の例です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/172826/3df14c8e-221a-771c-1e67-498637d7c607.png)

以上でカスタムロールが作成できました。

# おわりに

組み込みロールのところにも書きましたが、RBAC関連はまだ日本語訳が安定しておらず、今後の修正に期待です。
ここではなるべく"ロール"で統一しましたが、そもそもRoleの訳から"役割"・"ロール"に分かれて一定していない．．．
機能名についても、AWSに寄せてIAMを使っていくのかと思いましたが、今のところポータルのメニュー表記だけのようです。

# 参考資料

- [Azure PowerShell を使用したロールベースのアクセス制御の管理](https://docs.microsoft.com/ja-jp/azure/active-directory/role-based-access-control-manage-access-powershell) ：この手順の元にした資料
- [Azure Resource Manager のリソース プロバイダー操作](https://docs.microsoft.com/ja-jp/azure/active-directory/role-based-access-control-resource-provider-operations) ：リソースごとに実行可能なActionが確認できる
- [Azure ロールベースのアクセス制御の組み込みロール](https://docs.microsoft.com/ja-jp/azure/active-directory/role-based-access-built-in-roles) ：組み込みロールの一覧