Forms+LogicApps+Functions で申請・承認を経て仮想マシンを作成する

この記事は更新から24ヶ月以上経過しているため、最新の情報を別途確認することを推奨いたします。

はじめに

 仮想マシンを作成するために Excel で申請フォームを作成しメールでやりとりしている、承認を得るのに手作業でメール送信しているなど、業務フローが繁雑であるとき、Office 365 や Azure を使用すると業務を自動化できる場合があります。
 この記事では、そのような業務をシステム化するサンプルとして、Microsoft Forms から申請し、Logic Apps で承認を得た後、Functions を使用して仮想マシンを作成する業務フローを作成します。

 なお、Logic Apps と Power Automate はほぼ同じですが、Logic Apps を使用することで Azure サブスクリプションに存在し Power Automate のように個人のリソースに依存することがなくなるため、複数人が使う場合は Logic Apps をお勧めします。

Microsoft Forms の作成

 はじめに、 Forms にて申請フォームを作成します。
 簡素化するため、リソースグループ名、仮想マシン名、リージョン、仮想マシンのスペック、申請結果を受信するためのメールアドレスのみとします。

 以上で Forms の作成は完了です。

Azure Functions の作成

 次に、仮想マシンを作成する Functions を作成します。作成方法は以下の Blog を参照してください。
[Functions で仮想マシンの起動停止を行うには]
https://cloudsteady.jp/post/20796/

 違う点としてはふたつあり、ひとつ目はリソースグループや仮想ネットワークを作成するため、マネージド ID に対する役割を “共同作成者” にします。”仮想マシン共同作成者” ですと、リソースグループなどを作成するため権限が足りません。
 ふたつ目として、従量課金制の Functions タイムアウト値は 5分であり、仮想マシンの作成時間を超える場合があるため、タイムアウト値を 10分に設定します。設定するための host.json は、App Service Editor を用いてアクセスします。
[Azure Functions のスケールとホスティング]-[Function App タイムアウト期間]
https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-scale#function-app-timeout-duration
[Azure Functions の PowerShell 開発者向けガイド]
https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-reference-powershell 

 Function は 2つ作成します。後続の Logic Apps の HTTP 呼び出しが通常120秒であり、仮想マシン作成の処理時間を超えるためひとつの Function だとタイムアウトで終了してしまいます。

 このため、Logic Apps に用意されている長時間タスクのための仕組みである、webhook アクション パターンを適用します。ひとつ目の Function では HTTP ステータスコード 202 を一旦返却し、且つふたつ目の Function を呼び出します。ふたつ目の Function にて仮想マシンを作成します。

 仮想マシンは Forms から連携されるリソースグループ名、仮想マシン名、リージョン、スペック、webhook アクション パターンのためのコールバック URL を Functions に連携し作成します。

 以下はひとつ目の PowerShell サンプルです。

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.”

# リージョンや仮想マシンの設定
$region = $Request.Body.region.split(‘_’)[1]
$rg = $Request.Body.rg
$vmname = $Request.Body.vmname
$vmsku = $Request.Body.vmsku
$callbackUrl = $Request.Body.callbackUrl

$body = @{
“region” = $region;
“rg” = $rg;
“vmname” = $vmname;
“vmsku” = $vmsku;
“callbackUrl” = $callbackUrl;
} | ConvertTo-Json -Compress
Write-Host $body

$url = “ふたつ目の Function 呼び出し URL”
Invoke-WebRequest -Uri $url -Headers @{“Content-type”=”application/json”} -Method POST -Body $body

# Associate values to output bindings by calling ‘Push-OutputBinding’.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = [HttpStatusCode]::Accepted
Body = “要求受信”
})

 以下はふたつ目の PowerShell サンプルです。

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.”
Write-Host $Request.Body
Write-Host $Request.Body.rg

# リージョンや仮想マシンの設定
$location = $Request.Body.region
$resourceGroup = $Request.Body.rg
$vmName = $Request.Body.vmname
$vmSize = $Request.Body.vmsku

# VM ユーザーを設定
$user = “ユーザーIDを設定”
$pw = ConvertTo-SecureString -String “パスワードを設定” -AsPlainText -Force
$cred = New-Object -TypeName “System.Management.Automation.PSCredential” -ArgumentList $user,$pw

# ネットワーク設定
$subnet = “subnet” + $vmname
$vNet = “vNET” + $vmname
$pip = “pip$(Get-Random)”
$nic = “nic” + $vmname
$nsgRuleName = “RDPRule”
$nsgName = “NSG” + $vmname

# リソースグループ作成
New-AzResourceGroup -Name $resourceGroup -Location $location

# ネットワーク設定
$subnetConfig = New-AzVirtualNetworkSubnetConfig -Name $subnet -AddressPrefix 192.168.1.0/24
$vnet = New-AzVirtualNetwork -ResourceGroupName $resourceGroup -Location $location -Name $vNet -AddressPrefix 192.168.0.0/16 -Subnet $subnetConfig
$pip = New-AzPublicIpAddress -ResourceGroupName $resourceGroup -Location $location -Name $pip -AllocationMethod Static -IdleTimeoutInMinutes 4
$nsgRuleRDP = New-AzNetworkSecurityRuleConfig -Name $nsgRuleName -Protocol Tcp `
-Direction Inbound -Priority 1000 -SourceAddressPrefix * -SourcePortRange * -DestinationAddressPrefix * `
-DestinationPortRange 3389 -Access Allow
$nsg = New-AzNetworkSecurityGroup -ResourceGroupName $resourceGroup -Location $location -Name $nsgName -SecurityRules $nsgRuleRDP
$nic = New-AzNetworkInterface -Name $nic -ResourceGroupName $resourceGroup -Location $location -SubnetId $vnet.Subnets[0].Id -PublicIpAddressId $pip.Id -NetworkSecurityGroupId $nsg.Id

# VM 設定
$vm = New-AzVMConfig -VMName $vmName -VMSize $vmSize
$vm = Set-AzVMOperatingSystem -VM $vm -Windows -ComputerName $vmName -Credential $cred -ProvisionVMAgent -EnableAutoUpdate
$vm = Add-AzVMNetworkInterface -VM $vm -Id $nic.Id
$vm = Set-AzVMSourceImage -VM $vm -PublisherName ‘MicrosoftWindowsServer’ -Offer ‘WindowsServer’ -Skus ‘2019-Datacenter’ -Version latest
New-AzVM -ResourceGroupName $resourceGroup -Location $location -VM $vm
#Set-AzVMOSDisk -StorageAccountType “Standard_LRS”

# VM 作成
New-AzVM -ResourceGroupName $resourceGroup -Location $location -VM $vm

# Logic Apps 完了通知
Invoke-RestMethod -Method POST -Uri $Request.Body.callbackUrl -Body (@{ “success” = “1” } | ConvertTo-Json) -ContentType application/json

# Associate values to output bindings by calling ‘Push-OutputBinding’.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = [HttpStatusCode]::OK
Body = “作成成功”
})

 以上で Functions の作成は完了です。

Azure Logic Apps の作成

 最後に、Logic Apps にて承認フローを作成するとともに Forms と Functions を連携します。
 Logic Apps では、Forms のコネクタが用意されており、申請された瞬間をトリガーとして送信されたデータを取得することができます。

 次に承認フローを作成し、OK ならば Functions にデータ連携します。NG の場合、申請者にその旨を送信します。
 Function は、Logic Apps に用意されているコネクタではなく、HTTP webhook コネクタを使用します。
[Azure Logic Apps から呼び出しできるカスタム API の作成]-[webhook アクション パターンで長時間タスクを実行する]
https://docs.microsoft.com/ja-jp/azure/logic-apps/logic-apps-create-api-app#perform-long-running-tasks-with-the-webhook-action-pattern

 ふたつ目の Function ではコールバック URL に対して POST して完了したことを示すため、Logic Apps ではその POST された値にて成否を判断します。
 成功した場合は、Forms の連絡先アドレスへ、失敗した場合は任意の管理者へメールを送信します。

 以上で Logic Apps の作成は完了です。

まとめ

 上記を作成することで、Logic Apps から自動でメール送信され、且つ承認を行うと Function にて仮想マシンが作成されます。

 今回のサンプルはパラメータが少ないですが、仮想ネットワークや仮想マシンの ID/PW などパラメータを増やしたり、特定の仮想ネットワークにデプロイすることとし仮想マシンの種類のみを選択させたり、あるいは Ansible や Terraform などの構成管理ツールと連携させてリソース作成することなども考えられ、より現実的かと思います。リソース作成方法として、Functions ではなく Automation や仮想マシンで作成することも考慮します。

 なお、Azure にはガバナンスのための機能として、Azure ポリシーやAzure ブループリントがあります。サブスクリプション全体に渡り統制を効かせたい場合、これらの機能を使用することが適切です。

 この記事により、Forms や Logic Apps、Functions 等の利用促進になれば幸いです。

いいね (この記事が参考になった人の数:3)
(↑参考になった場合はハートマークを押して評価お願いします)
読み込み中...

注意事項・免責事項

※技術情報につきましては投稿日時点の情報となります。投稿日以降に仕様等が変更されていることがありますのでご了承ください。

※公式な技術情報の紹介の他、当社による検証結果および経験に基づく独自の見解が含まれている場合がございます。

※これらの技術情報によって被ったいかなる損害についても、当社は一切責任を負わないものといたします。十分な確認・検証の上、ご活用お願いたします。

※当サイトはマイクロソフト社によるサポートページではございません。パーソルクロステクノロジー株式会社が運営しているサイトのため、マイクロソフト社によるサポートを希望される方は適切な問い合わせ先にご確認ください。
 【重要】マイクロソフト社のサポートをお求めの方は、問い合わせ窓口をご確認ください