1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Azure Virtual Desktop の Start Virtual Machine on Connect と非公式な VM 内自己割り当て解除をやってみた

Posted at

背景と目的

Azure Virtual Desktop (AVD) の Start VM on Connect で VM の自動起動が出来ます。しかしながら、MS のドキュメントを見ると「ユーザーは、クライアントから VM をオフにできますか?」の中で VM の割り当ては解除されない、と書かれています。どうせなら、VM 内でシャットダウンする時に自身で割り当て解除出来たら、使っている時だけ課金されて、無駄なコストが発生しないハッピーな仕組みとなりますよね。

ということで、多少強引で非公式ではありますが、VM のマネージド ID にカスタムロールで割り当て解除権限を付与して自身の VM に権限を割り当て、VM 内で自己割り当て解除する Powershell スクリプトを実行する仕組みを試してみました。

前提条件

以前、私が書いたこちらの記事で作成した Azure Virtual Desktop (AVD) 環境を前提とします。

Start Virtual Machine on Connect

自動起動用のカスタムロールを作成します

bash
cat <<EOF > avd-startvm.json
{
    "Name": "Start VM on connect",
    "Description": "Start VM on connect with AVD",
    "IsCustom": true,
    "Actions": [
        "Microsoft.Compute/virtualMachines/start/action",
        "Microsoft.Compute/virtualMachines/read",
        "Microsoft.Compute/virtualMachines/instanceView/read"
    ],
    "DataActions": [
    ],
    "NotDataActions": [
    ],
    "AssignableScopes": [
        "/subscriptions/$(az account show --query id --output tsv)"
    ]
}
EOF

az role definition create \
  --role-definition @avd-startvm.json

作成したカスタムロールを Windows Virtual Desktop に割り当てます

bash
az role assignment create \
  --assignee $(az ad sp list \
  --display-name "Windows Virtual Desktop" \
  --query "[?displayName == 'Windows Virtual Desktop'].objectId" \
  --output tsv) \
  --role "Start VM on connect" \
  --resource-group ${prefix}-rg

ホストプールのプロパティ「接続時に VM を起動する」を「はい」にします

bash
az rest \
  --method patch \
  --uri https://management.azure.com/subscriptions/$(az account show --query id --output tsv)/resourceGroups/${prefix}-rg/providers/Microsoft.DesktopVirtualization/hostPools/${prefix}-hp?api-version=2021-01-14-preview \
  --body '{
    "properties": {
        "startVMOnConnect": true
    }
  }'

これで停止済み (割り当て解除)の VM を自動で起動出来るようになります。

非公式な VM 内自己割り当て解除

「割り当て解除」権限のみのカスタムロールを作成します

bash
cat <<EOF > avd-deallocateSvm.json
{
    "Name": "Self Deallocate for VM",
    "Description": "Self Deallocate for VM",
    "IsCustom": true,
    "Actions": [
        "Microsoft.Compute/virtualMachines/deallocate/action"
    ],
    "DataActions": [
    ],
    "NotDataActions": [
    ],
    "AssignableScopes": [
        "/subscriptions/$(az account show --query id --output tsv)"
    ]
}
EOF

az role definition create \
  --role-definition @avd-deallocateSvm.json

VM 自身にカスタムロールを割り当てます

bash
az role assignment create \
  --assignee $(az vm show \
  --resource-group ${prefix}-rg \
  --name ${prefix}-vm \
  --query identity.principalId \
  --output tsv) \
  --role "Self Deallocate for VM" \
  --scope $(az vm show \
  --resource-group ${prefix}-rg \
  --name ${prefix}-vm \
  --query id \
  --output tsv)

VM 内に下記のスクリプトを用意して実行します

powershell
$metadata = (Invoke-RestMethod -Headers @{"Metadata"="true"} -Method GET -Uri "http://169.254.169.254/metadata/instance?api-version=2021-02-01")
$resourceId = $metadata.compute.resourceId

$content = (Invoke-RestMethod -Headers @{"Metadata"="true"} -Method GET -Uri "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fmanagement.azure.com%2F")
$access_token = $content.access_token

Invoke-RestMethod -Headers @{"Authorization"="Bearer $access_token"} -Method POST -Uri "https://management.azure.com$resourceId/deallocate?api-version=2021-03-01"

すぐに「シャットダウン」と画面に表示されて、VM 割り当て解除処理が進みます。

参考

Start Virtual Machine on Connect

Azure PowerShell を使用してトークンを取得する

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?