PowerShellでAzureのカスタムロールの作成と適用


 概要

前回はAzure FunctionsとManagedIdentityを使って、
BlobStorageにデータを格納できた。

ただ、権限がOwner権限だったため必要最低限の権限に絞るようにしたい。
ので、試しにやってみた。

やったこととか目次

  1. カスタムロールの作成
  2. コードの修正
  3. Functionsへの適用
  4. ハマったこと
  5. 資料

カスタムロールの作成

PowerShellでのカスタムロールの作成の仕方を参考につらつら書く
今回の目的は以下なのでそれが叶うようにココを参考に設定ファイルを作成する

  • blobコンテナへの書き込み(上書き含む)

ポータルでのカスタムロール作成方法が公開されていたのでカスタムロールの作成はポータルからでもできる模様
(ただし2020/03/15現在preview機能)

{
    "Name": "Custom_blobStorageWriter",
    "Id": "5d722adf-39aa-43ea-990f-1ccc4d7bd40e", //作成する時(New-AzRoleDefinition実行時)は空文字
    "IsCustom": true,
    "Description": "Update&Write blobContainer",
    "Actions": [
        "Microsoft.Storage/storageAccounts/read",
        "Microsoft.Storage/storageAccounts/blobServices/containers/delete",
        "Microsoft.Storage/storageAccounts/blobServices/containers/write",
        "Microsoft.Storage/storageAccounts/listKeys/action" //Set-AzCurrentStorageAccountに必要(内部的にアクセスキーを取得している)
    ],
    "NotActions": [],
    "DataActions": [
        "Microsoft.Storage/storageAccounts/blobServices/containers/blobs/delete",
        "Microsoft.Storage/storageAccounts/blobServices/containers/blobs/write"
    ],
    "NotDataActions": [],
    "AssignableScopes": [
        "/subscriptions/[隠してる]" //SubscriptionIDを入れる
    ]
}

コードの修正

コード内でblobコンテナ名を取得しており、
read権限を不要にするため、処理を変更

using namespace System.Net

# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)

# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."

# Interact with query parameters or the body of the request.

(get-date) > .\date.txt

Disconnect-AzAccount
Connect-AzAccount -Identity

(Get-AzSubscription)[0]| Select-AzSubscription 

## そのうち環境変数とかにする
$storageName = "tklogstorage"
$ResourceGroupName = "discordBot"
$containerName = "logs"

Set-AzCurrentStorageAccount -ResourceGroupName $ResourceGroupName -StorageAccountName $storageName
Set-AzStorageBlobContent -File .\date.txt -Container $containerName -Force

## Get-AzStorageAccount/Get-AzStorageContainerの処理にread権限が必要なため変更
# $storageAccount Get-AzStorageAccount | ?{$_.StorageAccountName -eq $storageName}  
# $storageAccount | Get-AzStorageContainer  | ?{$_.name -eq "logs"} |Set-AzStorageBlobContent -force -File .\date.txt

# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = [HttpStatusCode]::OK
    Body = "end"
})

Functionsへの適用

PowerShellでのアクセス権の付与の仕方を参考にFunctionに対してロールを適用する

適用先としてObjectIDが必要なのでPowerShellなりPortalから確認する

New-AzRoleAssignment -ObjectId "3ba1b792-94ed-466e-8d75-a9560b89de31" ##上で確認したやつ
                     -RoleDefinitionName "Custom_blobStorageWriter"   ##カスタムロールの作成で作ったJsonのNameフィールド

参考リンクではSubscriptionの指定がしてるが、
カスタムロール内で指定していれば不要な模様

ハマったこと

カスタムロールのJsonは結構ハマった。
どの権限が必要か手探りでやったため、Functionsを都度実行して試したが、
Functionsはインスタンスを再起動しないと過去の設定をキャッシュしているようで変更が反映されなかった。

ただ、エラーログには必要な権限が表示されるので、
手順がわかってしまえばそこまで難しくないかなと。

資料

RBACの概要
PowerShellでのカスタムロールの作成の仕方
PowerShellでのアクセス権の付与の仕方
カスタムロール内で使うAction,DataActionの定義