Azure Powershell でAzureの課金情報をゲット(Billing API)

2018年10月19日

ついうっかり使いすぎて月末に泣かないように、日次で課金情報を取ろうと考えました。
自動で取得するとなるといちいちログインの必要のない、Azure REST API経由で取得します。

準備としてAzure Powershellをインストール。2015/11/23現在のバージョンは1.0.1となります。

memobog.azurewebsites.net

どうも1.0.0以上とそれ未満ではコマンドの仕様が違うらしく。
そもそもAzureのGUI管理インターフェイスはAzure管理ポータルとAzure Portal(Perview)の平行運用が続いており、Powershellもそれに合わせてSwitch-AzureModeでどちらのGUIに合わせた操作をするか選択する仕様だった。が、いちいちモードチェンジが必要なのが不評だったらしく、1.0.0からはSwitch-AzureModeは廃止、Azure Portalを操作するコマンドがAzure-RMなんちゃら~と着くようになったらしい。

statemachine.hatenablog.com

課金情報をゲット

結論から言うと、以下のページのコードが非常に使いやすく、コピペコピペでいけてしまう。

yomon.hatenablog.com

自分用に忘れそうな所だけをメモ。

キモとなるのは、認証用ヘッダーの作成と、アクセス先URLの作成。

$requestHeader = @{"Authorization" = $authHeader}
$usageUri = "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.Commerce/UsageAggregates?api-version=$apiVersion&reportedStartTime=$reportedStartTime&reportedEndTime=$reportedEndTime&aggregationGranularity=$granularity&showDetails=$showDetails"

認証用ヘッダー

# REST API実行用パラメータ設定
$clientId = "1950a258-227b-4e31-a9cf-717495945fc2" # Well-known client ID for Azure PowerShell
$redirectUri = "urn:ietf:wg:oauth:2.0:oob" # Redirect URI for Azure PowerShell
$resourceAppIdURI = "https://management.core.windows.net/" # Resource URI for REST API
$authority = "https://login.windows.net/$adTenant" # Azure AD Tenant Authority
(中略)
# Create Authentication Context tied to Azure AD Tenant
$authContext = New-Object -TypeName "Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext"  -ArgumentList $authority
# Acquire Azure AD token
$authResult = $authContext.AcquireToken($resourceAppIdURI, $clientId, $redirectUri, "Auto")
# Create Authorization Header
$authHeader = $authResult.CreateAuthorizationHeader()
  • $clientId
  • $redirectUri
  • $resourceAppIdURI

は固定値です。

RESTと言えばGUIから管理画面にログインして秘密鍵っぽい文字列を取得しスクリプトに埋め込む…というやつであるが、Azure REST APIの場合、テナントIDが秘密鍵的存在になるっぽい。なので「俺のテナントID、○○なんだよね~」って言いふらしてはダメです。

テナントIDは以下のコードで取得可能。

$adTenant = (Get-AzureSubscription -SubscriptionId $subscriptionId).TenantId

なのでテナントIDさえ取得しちゃえばコードは固定できる。アクセストークンの期限は1時間(だった?)なので、トークンだけは毎回取り直した方がよいです。

※ これ、サブスクリプションの管理者が複数いる場合、テナントIDは全員で共通なのかな…。一人がヘマしたら全員のリスクなんだが…。さすがに考えられてるとは思うが(僕のやり方がリスクあるだけかも)

アクセス先URL

$usageUri = "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.Commerce/UsageAggregates?api-version=$apiVersion&reportedStartTime=$reportedStartTime&reportedEndTime=$reportedEndTime&aggregationGranularity=$granularity&showDetails=$showDetails"

ここには

  • $subscriptionId
  • $apiVersion

を指定すればよい。
$subscriptionIdはadd-azureaccount後、Get-AzureSubscriptionすれば出てくるし、$apiVersionは"2015-06-01-preview"で固定なので問題なし。

まとめ

上記理解の元、コードをコピペコピペで発行すれば大丈夫。種別の絞り込みとかはpowershellの元々の知識を生かしてがんばる。

気になった点として、個人アカウントで仮想マシンが1つもないサブスクリプションだと「課金レポートを作ってるから5分ほど待ってくれ」って202が返ってきたことかな…。これは仮想マシンがないからそうなるのか、単純に個人のアカウントだから動作が違うのか、そこまでは調べてません。

Posted by tera