銀の光と碧い空

クラウドなインフラとC#なアプリ開発の狭間にいるエンジニアの日々

Azure VM のDiskのAttachとDetachをREST API経由でやってみる

AzureのLinux仮想マシンにDiskをAttach、DetachするのをAPIレベルの挙動で確認したかったので、REST APIを生で実行することにしました。

REST APIでは認証トークンが必要なのですが、まずはトークンを取得するためにサービスプリンシパルを作っておきます。Azure CLI 2.0で実行します。下のコマンドでは、リソースグループに対してContributorの権限を持つサービスプリンシパルを作ります。<resource_group_id>は最初のコマンドで表示されたidの値をいれ、それ以外の値は適宜置き換えてください。<app_name>は任意の名前です。

$ az group show -n <リソースグループ名> -o json
$ az ad sp create-for-rbac --name <app_name> --password <strong_password> --role contributor --scopes <resource_group_id>

あと、次の手順でテナントIDが必要なのでそれも取得しておきます。

$ az account show -o json

ここからはURLを直接たたくので、おすきなツールでどうぞ。Chrome拡張を使いました。まずは、認証トークンを取得します。このドキュメントの通りです。

docs.microsoft.com

つまり、https://login.microsoftonline.com/<tenantid>/oauth2/tokenというURLに対しapplication/x-www-form-urlencodedで次のような値を送信します。このあと帰ってきた値のaccess_tokenをメモしておきます。

client_id=<さっき作ったサービスプリンシパルのapp_id>
grant_type=client_credentials
client_secret=<さっき作ったサービスプリンスパルのパスワード>
resource=https://management.azure.com/

DiskのAttachとDetachですが、すべてVirtualMachineの更新というAPIを使います。

Virtual Machines - Create Or Update | Microsoft Docs

まずURLは https://management.azure.com/subscriptions/<tenantid>/resourceGroups/<リソースグループ名>/providers/Microsoft.Compute/virtualMachines/<仮想マシン名>/?api-version=2016-04-30-previewで、HTTPヘッダーにContent-Type: application/jsonと認証用にAuthorization: Bearer <さっき取得したaccess_tokenの値>をセットして、PUTで送信します。送信するBodyの中身は、何も接続されていない状態から1つAttachする場合はこんな感じになります。

{
    "properties": {
        "storageProfile": {
            "dataDisks": [
                {
                    "lun": <0とかLUNの値>,
                    "name": "<ディスクの名前>",
                    "createOption": "Attach",
                    "caching": "<Noneとか>",
                    "managedDisk": {
                        "storageAccountType": "<Standard_LRSとか>",
                        "id": "<diskのリソースID>"
                    },
                    "diskSizeGB": <ディスクサイズ>
                }
            ]
        }
    },
    "location": "<westus2とか>"
}

dataDisksに指定しているディスクの配列に仮想マシンにつながっているディスクを更新するので、最初の状態がわからない場合は、まずGETして、それに1つディスクを追加という形になります。 そして、ディスクを全部Detachする場合は送信するjsonだけ次のように変更します。

{
    "properties": {
        "storageProfile": {
            "dataDisks":[
            ]
        }
    },
    "location": "<westus2とか>"
}

実際にAPIを実行するとわかるのですが、API自体は数秒程度でレスポンスがかえってきます。が、ディスクのAttach、Detach自体はそこから操作が完了するまで時間がかかります。特にDiskのDetachは数分かかることがあって、そのときはAttachを再度実行するときにエラーがかえってきて気づくことになります。