Power AutomateとAzure AutomationによるAzureリソース昇格ロールリクエストの自動化

Power AutomateとAzure AutomationによるAzureリソース昇格ロールリクエストの自動化

Adam MaurerTechnical Leave a Comment

Image
1.選択した Azure サブスクリプション内で、portal.azure.com にアクセスし、Automation Account リソースを作成する。 すべてのリソース をクリックしてください。 追加.

a.オートメーション」を検索し 作成.

オートメーション

オートメーション作成フォームに必要なフィールドをすべて入力し、 をクリックします。 作成

Image

b.AzureAD モジュールをインポートする
c.これを行うには、先ほど作成したオートメーションアカウントを開き、以下を選択する。 モジュール を選択します。 ギャラリーを見るを検索する。 アズールエーディー.

モジュール

d.をインポートする。 アズールエーディー モジュールが正常に終了するまで待つ。

2.作成 ランブックス

a.オートメーションアカウントに移動し ランブックスをクリックする。 ランブックの作成.

ルブックス

b.ランブックが作成されたら 編集 をクリックし、PowerShellスクリプトを貼り付けます。 セーブ そして 出版.


3.以下のスクリプトを使用することができる。 ユーザーをコントリビューターロールに昇格させる を実行し、エラーが発生した場合はメールを送信します。このスクリプトは、まず、ユーザが昇格アクセス権を得たいサブスクリプションに既にリーダーロールが割り当てられているかどうかを検証します。もしそうでなければ、エラーになります。ユーザが要求されたリソースにContributorロールを既に持っている場合、これもエラーになります。

ハイライトされた部分は、あなたの環境の細部に合わせるべきである。

param (
[パラメータ(必須 = $true)]。
[文字列] $subscriptionId、
[パラメータ(必須 = $true)]。
[文字列] $resourceGroupName、
パラメータ(必須 = $true)] [文字列] $resourceGroupName
[文字列] $resourceName、
[パラメータ(必須 = $true)]。
[文字列] $resourceType、
パラメータ(必須 = $true)] [string] $userType
[文字列] $userPrincipalName、
パラメータ(必須 = $false)] [string] $userPrincipalName
[文字列] $linkUrl
)
$ErrorActionPreference = "続ける" $errors = @() 関数 Send-Email($subject, $body, $to, $cc = $null, $isBodyHtml = $false) { $credential = Get-AutomationPSredential -Name 'SMTP Relay' $credential = Get-AutomationPSCredential -Name 'SMTP Relay' $smtpServer = $credential = Get-AutomationPSCredential -Name 'SMTP Relay' 「smtp.example.com $smtpPort=。 <Int32 $from=から 'example@examplecompany.com' $mailParams = @{ メールパラメータ 宛先 = $to 件名 = $subject 本文 = $body SmtpServer = $smtpServer クレデンシャル = $credential ポート = $smtpPort UseSsl = $true 差出人 = $from BodyAsHtml = $isBodyHtml } If ($cc) { $mailParams $mailParams['Cc'] = $cc } 送信-MailMessage @mailParams -ErrorAction Stop } try { $connection = Connect-AzAccount -Identity } catch { $errors += "Managed Identity を使用した Azure との認証に失敗しました:$_" } try { { $errors Set-AzContext -SubscriptionId $subscriptionId } catch { $errors += "Azure サブスクリプションコンテキストの設定に失敗しました:$_" } $roleDefinitionName = 'Contributor' です。 $readerRoleDefinitionName = 'Reader' を試してください。 $user = Get-AzADUser -UserPrincipalName $userPrincipalName -ErrorAction Stop } catch { $errors $errors += "UPN '$userPrincipalName' のユーザーオブジェクトの取得に失敗しました。 } # サブスクリプションレベルで、ユーザがリーダーロールを持っているかチェックします。 $readerRoleAssignment = Get-AzRoleAssignment -ObjectId $user.Id -RoleDefinitionName $readerRoleDefinitionName -Scope "/subscriptions/$subscriptionId" -ErrorAction SilentlyContinue if (-not $readerRoleAssignment) { -Not $readerRoleAssignment $noReaderRoleHtml = @" <h2>読者役ではない</h2>
<p>ユーザー <strong>$userPrincipalName</strong> を持たない。 <strong>$readerRoleDefinitionName</strong> サブスクリプション・レベルのロールに追加することはできません。 <strong>$roleDefinitionName</strong> リソースの役割。</p> "@ $noReaderRoleHtml += $signature Send-Email -subject "Missing Reader Role" -body $noReaderRoleHtml -to $userPrincipalName -cc "itadministrator@examplecompany.com" -isBodyHtml $true 戻り値 } # リソースグループが存在するかチェックする $resourceGroupExists = $true $resourceGroup = Get-AzResourceGroup -Name $resourceGroupName -ErrorAction SilentlyContinue if (-not $resourceGroup) { $errors += 0 $errors += "リソースグループ '$resourceGroupName' が存在しません。" $resourceGroupExists = $false } # リソースグループ内にリソースが存在するか確認します。 $domain = "お名前.onmicrosoft.com" # これを実際のAADテナント・ドメインに置き換えてください。 # 名前とタイプの両方を使用して、リソースグループ内にリソースが存在するかどうかを確認します。 $resourceExists = $false $resourceUrl = "" if ($resourceGroupExists) { $resourceGroupExists $resources = Get-AzResource -ResourceGroupName $resourceGroupName -ResourceType $resourceType -Name $resourceName -ErrorAction SilentlyContinue $resource = $resources | Where-Object { $_.ResourceType -eq $resourceType -and $_.Name -eq $resourceName }. if ($resource) { $resourceExists $resourceExists = $true # ドメイン、リソースグループ、リソースタイプ、リソース名を使用して URL を構築します。 $resourceUrl = "https://portal.azure.com/#@$domain/resourcegroups/$resourceGroupName/providers/$($resource.ResourceType)/$resourceName" } else { $errors += "タイプ '$resourceType' で名前 '$resourceName' のリソースがリソースグループ '$resourceGroupName' に存在しません。" } } # リソースグループとリソースが存在する場合のみ、ロールの割り当てを試みる if ($resourceGroupExists -and $resourceExists) { $resourceExists tryする{ {。 $roleAssignment = New-AzRoleAssignment -ObjectId $user.Id -RoleDefinitionName $roleDefinitionName -Scope $resource.ResourceId -ErrorAction Stop。 をキャッチします。 if ($_.Exception -match 'Conflict') { $_.Exception #ユーザーは既にContributorロールを持っています。 $alreadyContributorHtml = @" <h2>すでに投稿しているユーザー</h2>             <p>ユーザー<strong>$userPrincipalName</strong>をすでに持っている。<strong>$roleDefinitionName</strong>リソースの役割<strong>$resourceName</strong>.</p>             <p>リソースURL:<a href='$linkUrl'>$linkUrl</a></p> "@ $alreadyContributorHtml += $signature Send-Email -subject "User Already Has Contributor Role" -body $alreadyContributorHtml -to $userPrincipalName -cc "itadministrator@examplecompany.com" -isBodyHtml $true } else { $errors += "ユーザー '$userPrincipalName' へのロール '$roleDefinitionName' の割り当てに失敗しました: $_" } } } $signature = @" <p>よろしく、</p> <p><strong>ITチーム</strong></p> <p><em>これは自動メッセージです。このメールに直接返信しないでください。</em></p> "@ もし ($errors) {なら $errorMessageHtml = "<h2>Azureロールの割り当てで検出された問題</h2><ul>" foreach ($errorItem in $errors) { { $errorItem in $errors $errorMessageHtml += "<li>$errorItem</li>" } $errorMessageHtml += "</ul>1TP57署名" Send-Email -subject "Azure Role Assignment Issues" -body $errorMessageHtml -to $userPrincipalName -cc "itadministrator@examplecompany.com" -isBodyHtml $true } elseif ($roleAssignment) { { { { $roleAssignment # 役割の割り当てに成功しました。 $successMessageHtml = @"<h2>役割分担の成功</h2>     <p>ユーザー<strong>$userPrincipalName</strong>の割り当てに成功した。<strong>$roleDefinitionName</strong>リソースの役割<strong>$resourceName</strong>.</p>     <p>リソースURL:<a href='$linkUrl'>$linkUrl</a></p> "@ $successMessageHtml += $signature Send-Email -subject "Azure Role Assignment Success" -body $successMessageHtml -to $userPrincipalName -cc "itadministrator@examplecompany.com" -isBodyHtml $true }

上記と下記のPowerShellスクリプトは、AzureADモジュールのロードに時間がかかるため、完了するまでに通常約5分かかることに注意してください。

また、Contributorのような新しいロールを追加する場合、ユーザーはログアウトしてAzureに戻るか、新しいロールを有効にするためにIncognito/Privateウィンドウを使用する必要があります。

4.定義された期間が経過したときにコントリビューターの役割を削除するために、2番目のランブックが作成されなければなりません。

このためのPowerShellスクリプトの例を以下に示す:

  param (
[パラメータ(必須 = $true)]。
[文字列] $subscriptionId、
[パラメータ(必須 = $true)]。
[文字列] $resourceGroupName、
パラメータ(必須 = $true)] [文字列] $resourceGroupName
[文字列] $resourceName、
[パラメータ(必須 = $true)]。
[文字列] $resourceType、
パラメータ(必須 = $true)] [string] $userType
[文字列] $userPrincipalName、
パラメータ(必須 = $false)] [string] $userPrincipalName
[文字列] $linkUrl
)

$ErrorActionPreference = "Continue"
$errors = @()
$signature = @" 

<p>よろしく、</p> <p><strong>ITチーム</strong></p> <p><em>これは自動メッセージです。このメールに直接返信しないでください。</em></p> "@ function Send-Email($subject, $body, $to, $cc = $null, $isBodyHtml = $false) {. $credential = Get-AutomationPSCredential -Name 'SMTP Relay' $smtpServer = 'smtp.example.com' $smtpPort=。<int 32> $from = 'example@examplecompany.com' $mailParams = @{ メールパラメータ 宛先 = $to 件名 = $subject 本文 = $body SmtpServer = $smtpServer クレデンシャル = $credential ポート = $smtpPort UseSsl = $true 差出人 = $from BodyAsHtml = $isBodyHtml } If ($cc) { $mailParams $mailParams['Cc'] = $cc } 送信-MailMessage @mailParams -ErrorAction Stop } try { $connection = Connect-AzAccount -Identity } catch { $errors += "Managed Identity を使用した Azure との認証に失敗しました:$_" } try { 以下のコマンドを実行する。 Set-AzContext -SubscriptionId $subscriptionId } catch { $errors += "Azure サブスクリプション コンテキストの設定に失敗しました:$_" } $roleDefinitionName = 'Contributor' です。 を試す。 $user = Get-AzADUser -UserPrincipalName $userPrincipalName -ErrorAction Stop } catch { $errors $errors += "UPN '$userPrincipalName' のユーザーオブジェクトの取得に失敗しました。 }

読者役ではない

リソースグループが存在するか確認し、リソースを取得する。
$resourceGroupExists = $resourceExists = $false
if ((Get-AzResourceGroup -Name $resourceGroupName -ErrorAction SilentlyContinue)) { $resourceGroupExists = $false
$resourceGroupExists = $true
$resources = Get-AzResource -ResourceGroupName $resourceGroupName -ResourceType $resourceType -Name $resourceName -ErrorAction SilentlyContinue
$resource = $resources | Where-Object { $_.ResourceType -eq $resourceType -and $_.Name -eq $resourceName }.

もし ($resource) {なら

$resourceExists = $true

} else { $resourceExists = $rue
$errors += "名前'$resourceName'を持つタイプ'$resourceType'のリソースがリソースグループ'$resourceGroupName'に存在しません。"
}
} else {

$errors += "リソースグループ '$resourceGroupName' が存在しません。"
}

# リソースグループとリソースが存在する場合、ロール割り当ての削除を試みる

if ($resourceGroupExists -and $resourceExists) { $resourceExists
を試す。

$roleAssignments = Get-AzRoleAssignment -ObjectId $user.Id -RoleDefinitionName $roleDefinitionName -Scope $resource.ResourceId -ErrorAction SilentlyContinue

foreach ($roleAssignments 内の $roleAssignment) { $roleAssignments 内の

# 注意: 確認の抑制は、コマンドレットがサポートしている場合に機能します。
Remove-AzRoleAssignment -ObjectId $user.Id -RoleDefinitionName $roleDefinitionName -Scope $resource.ResourceId -Confirm:$false

}

# ロール割り当てが正常に削除されたか確認する
if (-not (Get-AzRoleAssignment -ObjectId $user.Id -RoleDefinitionName $roleDefinitionName -Scope $resource.ResourceId -ErrorAction SilentlyContinue)) {。

# 削除が成功した場合、成功メールを送信します。
$successMessageHtml = @"<h2>役割除去の成功</h2> 
            <p>ユーザー<strong>$userPrincipalName</strong>からの削除に成功した。<strong>$roleDefinitionName</strong>リソースの役割<strong>$resourceName</strong>.</p>
            <p>リソースURL:<a href='$linkUrl'>$linkUrl</a></p> 
"@
$successMessageHtml += $signature
  Send-Email -subject "Azure Role Removal Success" -body $successMessageHtml -to $userPrincipalName -cc "itadministrator@examplecompany.com " -isBodyHtml $true
} else {
$errors += "ロール '$roleDefinitionName' は、削除を試みた後も、ユーザ '$userPrincipalName' に存在します。"
}

} catch {
$errors += "ユーザー '$userPrincipalName' からのロール '$roleDefinitionName' の削除に失敗しました: $_"
}

}

if ($errors) { { $errorMessage
$errorMessageHtml = "<h2>Azureロールの削除で検出された問題</h2><ul>"
foreach ($errors 内の $errorItem) { $errorMessageHtml +=
$errorMessageHtml += "<li>$errorItem</li>"
}
$errorMessageHtml += "</ul>$signature"
  Send-Email -subject "Azure Role Removal Issues" -body $errorMessageHtml -to $userPrincipalName -cc "itadministrator@examplecompany.com" -isBodyHtml $true

} 

5.サブスクリプションごとに、オートメーションアカウントにユーザーアクセス管理者ロールを与える。

a.PowerShell スク リプトを実行するには、 オート メーシ ョ ン ア カ ウ ン ト に User Access Administrator ロールが必要です。
b.b. 各サブスクリプション 昇格アクセスを許可したい場所。
c.役割」セクションで ユーザーアクセス管理者 をクリックします。 次の.

追加ロール割り当て

d.メンバー」セクションで 管理されたアイデンティティ では + 選抜メンバーを選択する。 サブスクリプション オートメーションアカウントが実行されている場所で、[Select]フィールドで マネージド ID とメンバーを選択します。

e.選択したメンバーが画面下部に表示されます。 選択 そして レビュー+アサイン.

Image

f.f. オートメーションアカウントエンタープライズアプリケーションは、サブスクリプショ ンで、以下のユーザーアクセス管理者ロールを持つものとして表示されます。 アクセスコントロール(IAM)

Image

6. Microsoft フォームを作成し、リソースの URL と、ビジネスニーズに応じて必要なその他の情報を要求します。以下の例では、ビジネス上の理由と、リソースへの昇格アクセスに必要な時間数を尋ねます。

azure-subscription-access-request

7.設定 セキュリティ・グループ オフィス管理

a.昇格アクセス要求が許可されるメンバーを割り当てます。(オプションですが、強くお勧めします。このセキュリティチェックを行いたくない場合は、以下のフロー作成 - ステップ9に進んでください)

アクティブ・チーム&グループ

b.セキュリティグループが作成されたら、URLにあるセキュリティグループIDをメモしてください。例えば、セキュリティグループIDはここにあるGUIDです:

https://admin.microsoft.com/Adminportal/Home#/groups/:/GroupDetails/xxxxxxxx-xxxxx-xxxxx-xxxxx-xxxxxxx/1インチ

8.portal.azure.com にアプリケーションを登録する。

a. 管理者の同意 以下の通り マイクロソフトグラフ タイプによるAPIパーミッション 申し込み:

      • ディレクトリ.Read.All
      • グループすべて読む
      • ユーザー
コンフィグパーミッション

b.を作成する。 クライアントの秘密 をメモしてください。 テナントIDには アプリケーション(クライアント)ID そして秘密 価値 流れのために。

顧客秘密

8.フォームデータを処理し、PowerShellスクリプトを実行するフローをセットアップする:

a.Microsoft Forms トリガー - 新しい応答が送信されたとき

b.Microsoft Forms アクション - トリガーの responseId からレスポンスの詳細を取得する。

c.セキュリティグループの推奨をスキップした場合は、以下のステップ10に進みます。

I.ユーザー(UPN)としてトリガーレスポンダを使用してユーザープロファイル(v2)を取得する

II.ユーザがセキュリティ・グループの一員であることを検証するために、URIへのHTTP GETリクエストを作成する: https://graph.microsoft.com/v1.0/groups/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/$filter=id eq 'outputs('Get_user_profile_(V2) ')?['body/id']'&$select=id

グラフィック・パート01

III.HTTP GETリクエストで、Authenticationを展開し、Authentication Typeが Active Directory OAuth観客は https://graph.microsoft.com/そして、Azureにアプリケーションを登録したときに表記した値が、それぞれのフィールドに追加される:

形

IV.リクエストが拒否された場合、IT管理者に電子メールを送信する]は、セキュリティグループの検証でレコードを取得できなかった場合に実行されるように設定されています。そして、要求者にそのような要求ができるセキュリティグループに属していないことを通知するメールが送信されます。

Image

V.上記のセキュリティ・チェックは、マイクロソフト・フォームのアクセスで直接管理することもできますが、セキュリティ・グループの方がメンテナンスが少なくて済む安全なソリューションであることは注目に値します:

設定

10.昇格アクセスを得るために提供された URL が、昇格アクセスを要求することを許可するサブスクリプションのリストに含まれているかどうかをチェックする条件を作成します。

Image

a.提供された URL からサブスクリプションを解析するには、ハイライトされた Get_response_details 値をフォームの URL フィールドに置き換えて、以下の式を使用します:

first(split(last(split(body('Get_response_details')?['URLfieldID'],'/resource/subscriptions/')),'/resourceGroups/'))

b.URL がリストにないサブスクリプションのものである場合、投稿者に拒否メールを送信する。

c.URL のリストにサブスクリプションが含まれている場合は、Azure Automation ジョブの作成に進みます。

11.Azure Automation アクションで、ハイライトされた値をすべて入力し、Contributor の昇格アクセス権を付与する Runbook を指していることを確認します。

a.サブスクリプション = ランブックがあるサブスクリプション

b.リソースグループ = ランブックがあるリソースグループ

c.自動化アカウント = 以前に設定した自動化アカウント b

d.ランブック名 = コントリビューターロールを付与するランブックの名前

e.Runbookを選択すると、PowerShellスクリプトのParametersに必要な詳細が入力されます。フォーム送信時に提供されたURLからこの情報を解析します:

I.サブスクリプションID

first(split(last(split(body('Get_response_details')?['URLfieldID'],'/resource/subscriptions/')),'/resourceGroups/'))

II.リソースグループ名

first(split(last(split(body('Get_response_details')?['URLfieldID'],'/resourceGroups/')),'/providers/'))

III.リソースグループ名

first(split(first(split(last(split(body('Get_response_details')?['URLfieldID'],'/providers/')),concat('/',last(split(body('Get_response_details')?URLfieldID'],'/'))),concat('/',last(split(first(split(last(split(body('Get_response_details')?['URLfieldID'],'/providers/')),concat('/',last(split(body('Get_response_details')?URLfieldID'],'/'))))),'/')))))

IV.UserPrincipalName

ボディ('Get_response_details')?

V.リソース名

last(split(first(split(last(split(body('Get_response_details')?['URLfieldID'],'/providers/')),concat('/',last(split(body('Get_response_details')?URLfieldID'],'/'))))),'/'))

VI.リンクURL

body('Get_response_details')?URLfieldID']

フォーム02
ResourceTypeは、スクリプトの実行には技術的には必要ないことに注意。 リソースグループ内の各リソース名が一意であることを保証する命名規則がある場合に限ります。 コントリビューターロールの付与におけるエラーを避けるために、スクリプト内に保持することを推奨します。

12.この例では、ユーザーが昇格アクセスを必要とする時間を定義できるようにしている。Delay]では、[Count]はフォームフィールドに入力された時間数で定義され、[Unit]は[Hour]です。

13.Delay の後、新しい Azure Automation アクションを作成し、今回は、特定のリソース上のユーザーの Contributor ロールを削除する Runbook を指定します。

a. フィールドは、それぞれのパラメータの解析と同様に、コントリビューターロールを付与するフィールドと同じです。

このフローを応用したり、追加したりすることができるアイデアはいくつかあるが、ここでは割愛する:

  1. Microsoft Formsではなく、社内のチケットシステムをトリガーとして使用する。
  2. リソースグループおよび/またはサブスクリプションレベルのアクセスを、ユーザーのニーズに応じて選択できるようにします。この場合、いくつかの解析式が変更されることを理解してください。
  3. リクエストを承認または拒否する権限を持つ個人またはグループに送信される承認フローを追加します。
アダム

アダム・マウラー

Connecting SoftwareのCOO

著者。

Connecting Softwareの最高執行責任者として、各拠点における日々の業務を管理しています。私は、継続的な改善と効率の向上に情熱を注いでいます。スロバキアまたはマデイラの素晴らしいチームに参加したい方は、ぜひご連絡ください。


オンラインでもっと情報が得られますか?

Exchangeサーバーの同期については、当ブログの他の記事をご覧ください:

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

For security, use of Google's reCAPTCHA service is required which is subject to the Google Privacy Policy and Terms of Use.