このエントリはこちらのブログの日本語版になります。
AzureにたてたLinux仮想マシンをdeallocateしたい場合、Azure Portalにログインできればそこからログインしたり、REST APIを実行する権限を作って適宜プログラムからdeallocateすることができます。しかし、そのLinuxにログインできる権限しか無い場合、OSのshutdown
コマンドを実行してもdeallocate
はされないため、仮想マシンの利用料金はかかり続けます。そこで仮想マシンの中からdeallocateするようにしてみたいと思います。
deallocate
するにはREST APIを実行する必要があるので、Azure CLI 2.0をインストールして、Azure AD APPでService Principalを作成して認証を行います。もちろんService Principalのパスワードを指定してもいいのですが、パスワードを平文で保存することが懸念の場合は、Managed Service Identity (MSI)を利用してパスワードを利用せずに認証することができます。今回はその方法を紹介することにします。
対象となるLinux仮想マシンにAzure CLI 2.0がインストールされていない場合はインストールします。yum形式でのインストールは次のようにおこないます。
$ sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc $ sudo sh -c 'echo -e "[azure-cli]\nname=Azure CLI\nbaseurl=https://packages.microsoft.com/yumrepos/azure-cli\nenabled=1\ngpgcheck=1\ngpgkey=https://packages.microsoft.com/keys/microsoft.asc" > /etc/yum.repos.d/azure-cli.repo' $ sudo yum install azure-cli
次に仮想マシンに対しMSIを有効にします。Azure Cloud ShellなどAzure CLI 2.0を利用する場合は次のコマンドを実行します。
$ az vm identity assign -g <resrouce_group_name> -n <vm_name>
次にこの仮想マシンに実行できるIAM Roleを付与します。今回は同じ仮想マシンに対するVirtual Machine Contributor
ロールを付与することにします。最初のコマンドで仮想マシンのリソースIDを取得し、次のコマンドで先程与えたMSIのサービスプリンシパルIDを取得します。取得いた値を3番目のコマンドに与えて、ロールを付与しています。
$ az vm show -g <resrouce_group_name> -n <vm_name> --query id $ az resource list -n <vm_name> --query [*].identity.principalId --out tsv $ az role assignment create --assignee <vm_resource_id> --role 'Virtual Machine Contributor' --scope <sp_id>
これで準備は完了です。仮想マシン側でdeallocateするためのスクリプトを次のように作っておきます。MSIを利用したログインは--msi
オプションで実行できます。また、deallocateするために自分自身のリソースグループ名と仮想マシン名が必要です。スクリプトにべた書きしてもいいですが、せっかくなのでインスタンスメタデータサービスを使って取得してみました。これで同一のスクリプトを好きな仮想マシンに配置するだけで実行できるようになります。このスクリプトであればcronでスケジュール実行することもできるでしょう。
#!/bin/bash response=$(curl -H Metadata:true "http://169.254.169.254/metadata/instance/compute?api-version=2017-12-01" -s) resource_group=$(echo $response | python -c 'import sys, json; print (json.load(sys.stdin)["resourceGroupName"])') vm_name=$(echo $response | python -c 'import sys, json; print (json.load(sys.stdin)["name"])') az login --msi az vm deallocate -g $resource_group -n $vm_name
また、MSIを利用しない場合は、サービスプリンシパルを設定したAzure AD Appを作成し、パスワードを指定してAzure CLI 2.0のログインコマンドを実行するとよいでしょう。