🧙‍♂️

[Azure]テナント内のRBAC一覧をスクリプトで取得する

2023/03/26に公開

監査や構成管理の観点から付与したRBACを一覧で管理できるようにしたおきたいというニーズはAzureを使っている企業ならどこにでもあると思います。
ただし安易に手動更新するスプレッドシートなどを作成すると更新が漏れるべくして漏れますし、そもそも都度都度更新するのは非常に面倒なので全力で避けたいところです。

なのでなるべく楽にRBACを管理できるようにまずはRBAC一覧をスクリプトからCSV形式で取得できるようにします!
スクリプトにはPowerShellを使用します。

そもそもどのような情報があればいいのか

5W1HでRBACの管理要素を整理してみます。

5W1H 要素 APIのプロパティ※1
①:Where どのスコープに付与したのか? scope
②:What 何の権限(ロール)を付与したのか? roleDefinitionId
③:Why なぜ付与したのか? Description※2
④:Who 誰(ユーザ/グループ/サービスプリンシパル)への付与なのか? principalId
⑤:Who 誰が付与したのか? createdBy
⑥:Who 誰が更新したのか? updatedBy
⑦:When いつ付与したのか? createdOn
⑧:When いつ更新したのか? updatedOn
⑨:How どのような方法で付与したのか?(CLI/GUI) なし※3
  • ※1…以下を参照

https://learn.microsoft.com/ja-jp/rest/api/authorization/role-assignments/get?tabs=HTTP

  • ※2…人間の頭にある情報なのでRBACと紐づけて都度記録しておく必要がありますが、RBACのDescriptionに記録する運用にしておけばAzure上で管理できます。(後付けで既にあるRBACに情報を追記したい場合はSet-AzRoleAssignmentなどを使いましょう)
  • ※3…取得できません。(あえて管理する必要もない要素なので、①〜⑧を取得対象とします)

どうやって情報を取得するのか

APIを直接叩くこともできますが、Get-AzRoleAssignment(Azure Powershell)az role assignment list(Azure CLI)から取得するのが一番簡単です。principalIdやroleDefinitionIdの表示名もよしなに一緒に取得してくれるというメリットもあります。

Azure Powershellで取得する場合の注意点
Azure PowershellのGet-AzRoleAssignmentは、戻り値のオブジェクトのクラス内で⑤~⑧のプロパティが定義されておらず、取得できない仕様になっています。Powershellで扱う分にはAzure Powershellの方が直接オブジェクトとして扱えるので便利ですが、この手の罠が多そうですね…

PS /home/dev> Get-AzRoleAssignment | Get-Member
   TypeName: Microsoft.Azure.Commands.Resources.Models.Authorization.PSRoleAssignment
(略)

https://learn.microsoft.com/en-us/dotnet/api/microsoft.azure.commands.resources.models.authorization.psroleassignment?view=az-ps-latest

実装

基本的には取得したJSONをパース/加工してCSVに出力するだけなのでシンプルです。
Cloud Shellからの利用を想定して動作環境はAzure Powershell 7.3.3です。
RBACのスコープとなりうる管理グループ/サブスクリプション/リソースグループ/リソースについたRBACをテナント内から網羅的に取得できるようにします。

function ConvertTo-PsObject($json){
    $json | ConvertFrom-Json
}

$role_assingments = @()
$subscriptions = ConvertTo-PsObject (az account list --all)

foreach($subscription in $subscriptions){
    az account set --name $subscription.name
    $role_assingments += ConvertTo-PsObject (az role assignment list --all)
}

#重複排除が必要
$role_assingments = $role_assingments | Sort-Object -Property id -Unique

#変換+フォーマットした時刻プロパティを後付け
for($i=0;$i -lt $role_assingments.length;$i++){
    $role_assingments[$i] `
        | Add-Member -MemberType NoteProperty  -Name 'CreatedOnJST' -Value $role_assingments[$i].CreatedOn.AddHours(9).Tostring('yyyy/MM/dd HH:mm:ss')
    $role_assingments[$i] `
        | Add-Member -MemberType NoteProperty  -Name 'UpdatedOnJST' -Value $role_assingments[$i].UpdatedOn.AddHours(9).Tostring('yyyy/MM/dd HH:mm:ss')
}

$role_assingments `
    | Select-Object createdOnJST,createdBy,updatedOnJST,updatedBy,scope,roleDefinitionName,principalName,description `
    | Export-Csv -Encoding Default $psscriptroot\role_assignments.csv

サンプル

Cloud Shellから実行してCSVを取得できました!

PS /home/dev> ./get_roleassign.ps1
PS /home/dev> Get-Content ./role_assignments.csv
"CreatedOnJST","createdBy","UpdatedOnJST","updatedBy","scope","roleDefinitionName","principalName","description"
"2023/01/02 21:01:01","***","2023/01/02 21:01:01","***","/providers/Microsoft.Management/managementGroups/mg-test","Owner","***",
"2023/03/26 09:04:55","***","2023/03/26 09:04:55","***","/subscriptions/8d76c2b5-c7bf-4821-9666-92fd4b6313cc/resourceGroups/rg-test-jpeast-vm","Contributor","***","基盤リソースを構築するため"

注意点など

  • 認証処理はCloud Shellの利用を想定してスキップしています。
  • 当然ながら、実行ユーザもしくはサービスプリンシパルにはすべてのスコープでRBACを閲覧できる権限が必要です。
  • サブスクリプション配下のリソースグループやリソースのRBACを再帰的に取得できるようにaz role assignment listには'--all'を付けます。
  • 複数のサブスクリプションがある環境では管理グループをスコープとしたRBACが重複してしまうため、重複排除が必要になります。
  • 日時の戻り値はUTCなので、JSTへの変換やフォーマットの変更はスクリプト側で行います。
  • Azure CLIやAzure Powershellの実行スコープは基本的にサブスクリプション単位になっています。それなりの会社規模でテナント内に複数のサブスクリプションがある環境ではサブスクリプションの数だけコマンドを実行するようにしないと漏れます。

https://learn.microsoft.com/ja-jp/cli/azure/manage-azure-subscriptions-azure-cli?view=azure-cli-latest#get-the-active-subscription

https://learn.microsoft.com/ja-jp/powershell/azure/context-persistence?view=azps-9.5.0

まとめ

簡易的ながら最新のRBAC一覧がスクリプトでいつでも取得できるようになりました。
上記のスクリプトを定期実行させアウトプットをどこかに保存する仕組みを用意することで、RBACの構成管理が自動化が可能になりますが、また別の記事でまとめたいと思います。

Discussion