セイテクエンジニアのブログ かつて山市良と呼ばれたおじさんのブログ vol.56 はじめてのAzure REST API|Azure&Entra IDスクリプト大作戦(3)
2024年10月31日配信
執筆者:山内 和朗
前々回(vol.54)、前回(vol.55)と、Azure PowerShellのスクリプトによる自動化に挑戦してきました。前回、自動化の制約を取り除く方法として「サービスプリンシパル」による「非対話型認証」を検証しました。今回は、前回作成したのと同じサービスプリンシパルを、追加設定なしでそのまま利用して、Azure REST APIからリソースの情報を取り出してみます。
「Representational State Transfer(REST) API」は、一連のHTTP操作(GET、POSTメソッドなど)をサポートするサービスエンドポイントであり、サービスのリソースに関する情報の取得や、操作(作成、削除、更新)のためのアクセスを提供する、Webベースのアプリケーションやサービスではごく一般的なものです。REST APIには、HTTP/HTTPSを使用して任意のHTTPクライアントからアクセスすることができます。Azure REST APIは、Azureのリソースに対するアクセスを提供します。Microsoft Entra IDやMicrosoft 365、Microsoft Intuneなどのサービスについては、Microsoft Graph REST APIが別に用意されています。
Azure REST API リファレンス|Azure(Microsoft Learn)
Microsoft Graph API を使用する|Microsoft Graph(Microsoft Learn)
Azure REST APIには、前回準備した、パスワード(クライアントシークレット)ベースの認証を利用可能にし、Azureのサブスクリプションレベルで「閲覧者」ロールのアクセス権限を与えたサービスプリンシパルをそのまま使用します(画面1)。
画面1 Azure REST APIへのアクセスに使用するサービスプリンシパル
Azure REST APIからリソースの情報を取得するには、最初にサービスプリンシパルのアクセストークンを取得し、そのアクセストークンを用いてAzure REST APIを呼び出します。Azure REST APIリファレンスには、curlを使用して呼び出す方法が説明されていますが、今回はWindows PowerShell(powershell.exe)またはPowerShell(pwsh)のInvoke-RestMethodを使用してみます。PowerShellのウィンドウを開いたら(管理者権限は不要)、次のコマンドラインを順番に実行してください。これで、アクセストークンが$accesstoken変数に格納されます(画面2)。なお、「アプリケーション(クライアント)ID」「クライアントシークレットの値」「サブスクリプションID」「テナントID」の取得方法については、前回のブログをご覧ください。
$clientid = "アプリケーション(クライアント)ID" $clientsecret = "クライアントシークレットの値" $subscriptionid = "サブスクリプションID" $tenantid = "テナントID" $resource = "https://management.azure.com/" $tokenendpoint = "https://login.microsoftonline.com/$tenantid/oauth2/token" $body = @{ grant_type = "client_credentials" resource = $resource client_id = $clientid client_secret = $clientsecret } $tokenresponse = Invoke-RestMethod -Method Post -Uri $tokenendpoint -Body $body -ContentType "application/x-www-form-urlencoded" $accesstoken = $tokenresponse.access_token |
画面2 Invoke-RestMethodを使用してサービスプリンシパルのアクセストークンを取得する
アクセストークンを取得したら、お好みのAzure REST APIを使用してリソースの情報を取得します。例えば、以下のAPIを使用すると、Azure仮想マシン(VM)の一覧を取得できます。なお、Azure REST APIリファレンスの日本語ページはナビゲーション(ページ左側のツリー)がうまく機能しておらず、目的のAPIを探すのに苦労するため、英語ページで探すことをお勧めします。
Virtual Machines - List(英語)|Azure REST API(Microsoft Learn)
アクセストークンを取得したのと同じウィンドウで引き続き次のスクリプトを実行します。具体的には、アクセストークンを含むHTTP要求のヘッダーを作成し、Invoke-RestMethodコマンドレットを使用してGETメソッドを実行し、その応答を取得します。応答結果はAPIからJSON形式で返ってきますが、Invoke-WebReuestコマンドレットとは異なり、Invoke-RestMethodコマンドレットはJSON形式の値をPowerShellオブジェクトに自動的に変換してくれます(画面3)。JSON形式で取得したい場合は、オブジェクトをパイプを使ってConvertTo-Jsonコマンドレットに渡します(画面4)。
$headers = @{ 'Authorization' = "Bearer $accesstoken" 'Content-Type' = 'application/json' } $requesturi = "https://management.azure.com/subscriptions/$subscriptionid/providers/Microsoft.Compute/virtualMachines?api-version=2024-07-01" $ret = (Invoke-RestMethod -Uri $requesturi -Headers $headers -Method Get) $ret $ret | ConvertTo-Json -Depth 10 |Set-Content "~¥vmlist.json" notepad $env:USERPROFILE¥vmlist.json |
画面3 アクセストークンを使用して、Virtual Machines - Lists APIから情報を取得する
画面4 Invoke-RestMethodはJSON形式の値をPowerShellオブジェクトに自動変換して扱いやすくしてくれる。ConvertTo-JsonでJSON形式に戻すことも可能
前回は、Azure PowerShellへのアクセスに、クライアントシークレットの値を暗号化された標準文字列に変換してテキストファイルに保存し、セキュリティで保護された文字列(System.Secure.SecureString)を取り出して使用しました。同じテキストファイルをAzure REST APIへのアクセスにも使用したい場合は、上記の$clientseret=の行を以下の3行に置き換えます。最後のコマンドラインにより、$clientsecret変数にはプレーンテキスト形式のクライアントシークレットの値が格納されます。
|
「Azure REST API リファレンス」には、curlを使用したAzure REST APIへのアクセスについて説明されています。ただし、公式ドキュメントに具体的な手順はしめされておらず、外部コミュニティのブログ記事が案内されているにすぎません。
curlをファイルのダウンロードにしか使ったことのない私には少し難しいのですが、これについても挑戦してみました。次の2行のコマンドラインを実行することでVMの一覧の取得に成功しました(画面5)。
curl -X POST "https://login.microsoftonline.com/サブスクリプションID/oauth2/token" -F grant_type=client_credentials -F resource=https://management.core.windows.net/ -F client_id="アプリケーション(クライアント)ID" -F client_secret="クライアントシークレットの値" curl -v -X GET -H "Content-Type: application/json" -H "Authorization: Bearer アクセストークン文字列" -H "Host: management.azure.com" https://management.azure.com/subscriptions/サブスクリプションID/providers/Microsoft.Compute/virtualMachines?api-version=2024-07-01 |
画面5 Windows標準のcurl.exeを使用して、アクセストークンを取得し、Azure REST APIにアクセスしてVMの一覧を取得した例
Windowsバージョン1803以降およびWindows Server 2019以降には、curlが標準搭載されており、PowerShellウィンドウやコマンドプロンプトから利用することができます。ただし、WindowsのPowerShell(Powershell.exeやpwsh.exe)でcurlを実行すると、C:¥Windows¥System32¥curl.exeではなく、Invoke-WebRequestのエイリアスとしてのcurlが実行されてしまい。返ってくるエラー(“Invoke-WebRequest : パラメーター名 'X' に一致するパラメーターが見つかりません。”など)に悩むことになります。WindowsのPowerShellウィンドウから実行する場合は、curl.exeと拡張子を含めてください。
curlは私には扱いにくいので、PowerShellでスクリプト化してみたいと思います。とりあえず、自分の勉強と検証用に、Azure REST APIからリソース情報を取得するPowerShellサンプルスクリプト(getjsonfromazrest.ps1、プレーンテキストで表示)を作ってみました。サブスクリプション情報、リソースグループの一覧、Azure VMの一覧(APIは後から追加することを想定)と、カスタムURLの入力をメニューから選択して、結果をPowerShellオブジェクトとして返すものです。ファイルパスを指定すれば、JSON形式でファイル出力も可能です。ただし、エラー処理など全く考慮していない点にご注意ください。あくまでも自分(私)用ですので、詳しい説明も省きますが、XXXXの部分をお使いの環境に合わせて書き換えれば活用できると思います。
画面6 Azure REST APIからリソース情報を取得するPowerShellサンプルスクリプト(getjsonfromazrest.ps1)