Azure Billing API(課金API)をPowerShellから試してみた

Azureの課金情報取得のAPIが遂に出ました。weblogs.asp.net


早速、こちらの記事で認証方法などを参考に、課金レートのAPIも組み合わせて作ってみました。blogs.technet.com


仕様は以下の通り

  • 取得日から過去30日分のデータを対象
  • 対象のデータは仮想マシンの稼働データのみ(※Storageなどカテゴリによっては若干特性がありそうなので、それぞれ調整が必要そうです)
  • 出力はとりあえずOut-GridView
  • データは日次ベース(時間ベースの取得も可能)
  • 料金プランは従量課金契約の課金データをベース(変数offerDurableIDをこちらのURLに合わせて変更できます)
  • 現時点では仮想マシンの場合、個別の仮想マシン情報までは取れなくて、クラウドサービス毎までの情報しか取れないようです。将来instanceDataのフィールドが取れるようになれば個別の仮想マシンのデータもいけるようになるかも

 
 

# 日付設定(30日前から実行日までのデータ取得)
$reportedStartTime = (Get-Date).AddDays(-30).ToString("yyyy-MM-dd")
$reportedEndTime = (Get-Date).ToString("yyyy-MM-dd")

# Azure認証設定
Add-AzureAccount
$subscriptionId = 
    (Get-AzureSubscription |
     Out-GridView `
        -Title "Select an Azure Subscription ..." `
        -PassThru).SubscriptionId

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

# 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


# Load ADAL Assemblies
$programDir = ${env:ProgramFiles(x86)}
if(!$programDir)
{
    $programDir = ${env:ProgramFiles}
}
$adal = "$programDir\Microsoft SDKs\Azure\PowerShell\ServiceManagement\Azure\Services\Microsoft.IdentityModel.Clients.ActiveDirectory.dll"
$adalforms = "$programDir\Microsoft SDKs\Azure\PowerShell\ServiceManagement\Azure\Services\Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll"
Add-Type -Path $adal
Add-Type -Path $adalforms

# 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()

# Set REST API parameters
$apiVersion = "2015-06-01-preview"
$granularity = "Daily" # Can be Hourly or Daily
$showDetails = "true"
$contentType = "application/json;charset=utf-8"

# Set HTTP request headers to include Authorization header
$requestHeader = @{"Authorization" = $authHeader}

# 課金情報の基になるリソース利用状況を REST APIから取得(今回は仮想マシン部分のみ)
$usageUri = "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.Commerce/UsageAggregates?api-version=$apiVersion&reportedStartTime=$reportedStartTime&reportedEndTime=$reportedEndTime&aggregationGranularity=$granularity&showDetails=$showDetails"
$vmMeterName     = "Compute Hours"
$vmMeterCategory = "Virtual Machines"
$vmUsageData = @()
Do {

    $usageData = Invoke-RestMethod `
        -Uri $usageUri `
        -Method Get `
        -Headers $requestHeader `
        -ContentType $contentType

    $vmUsageData += $usageData.value.properties | 
        where{
                ($_.MeterName -eq $vmMeterName) -and
                ($_.MeterCategory -eq $vmMeterCategory)
            } | select usageStartTime,usageEndTime,meterName,meterCategory,meterSubCategory,unit,quantity -ExpandProperty infoFields
    $usageUri = $usageData.nextLink
} until (!$usageUri)



# 課金レートの基になる情報を REST APIから取得(今回は従量課金プランを利用)
$offerDurableID = "MS-AZR-0003p" #参照URL http://azure.microsoft.com/en-us/support/legal/offer-details/
$currency = "JPY"
$locale = "en-US"
$region = "JP"
$rateCardUri = "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.Commerce/RateCard?api-version=$apiVersion`&`$filter=OfferDurableId eq '$offerDurableID' and Currency eq '$currency' and Locale eq '$locale' and RegionInfo eq '$region'"
$rateCardData = Invoke-RestMethod `
        -Uri $rateCardUri `
        -Method Get `
        -Headers $requestHeader `
        -ContentType $contentType


#リソース利用状況と課金レートから価格kを計算
$calculatedData = @()
foreach($data in $vmUsageData)
{
    $rateInfo = $rateCardData.Meters | 
        where{
            ($_.MeterName -eq $data.meterName) -and 
            ($_.MeterCategory -eq $data.meterCategory) -and 
            ($_.MeterSubCategory -eq $data.meterSubCategory) -and
            ($_.Unit -eq $data.unit)
            }
    
    $price = 0
    if($rateInfo)
    {
        $rateData = $rateInfo | where{$_.MeterRegion -eq $data.meteredRegion}
        if(!$rateData)
        {
            $rateData = $rateInfo | where{!$_.MeterRegion}
        }
        $price = ($rateData.MeterRates.0) * $data.quantity
    }
    $calculatedData += $data |
        Add-Member -NotePropertyName MeterRates -NotePropertyValue ($rateData.MeterRates.0) -PassThru |
        Add-Member -NotePropertyName Price -NotePropertyValue $price -PassThru 

}

# GridViewに出力
$calculatedData | Out-GridView

f:id:yomon8:20150630132046p:plain



2015/07/15追記

Azure Resource ManagerのPowerShellコマンドレットを使って書き換えてみました。

# 日付設定(30日前から実行日までのデータ取得)
$reportedStartTime = (Get-Date).AddDays(-30).ToString("yyyy-MM-dd")
$reportedEndTime = (Get-Date).ToString("yyyy-MM-dd")
Switch-AzureMode -Name AzureResourceManager

# Azure認証設定
Add-AzureAccount
Get-AzureSubscription | Out-GridView -Title "Select an Azure Subscription ..." -PassThru | Select-AzureSubscription


# Set API parameters
$apiVersion = "2015-06-01-preview"
$granularity = "Daily" # Can be Hourly or Daily
$showDetails = "true"
$contentType = "application/json;charset=utf-8"


# 課金情報の基になるリソース利用状況を REST APIから取得(今回は仮想マシン部分のみ)
$granularity = "Daily"
$showDetails = $true
$vmUsageData = @()
$continuationToken = $null
$vmMeterName     = "Compute Hours"
$vmMeterCategory = "Virtual Machines"

Do {

    $usageData = Get-UsageAggregates `
        -ReportedStartTime $reportedStartTime `
        -ReportedEndTime $reportedEndTime `
        -AggregationGranularity $granularity `
        -ShowDetails:$showDetails `
        -ContinuationToken $continuationToken
    $vmUsageData += $usageData.UsageAggregations.properties |
                        where{
                            ($_.MeterName -eq $vmMeterName) -and
                            ($_.MeterCategory -eq $vmMeterCategory)
                        } | select usageStartTime,usageEndTime,meterName,meterCategory,meterSubCategory,unit,quantity -ExpandProperty infoFields
       

    if ($usageData.NextLink) {

        $continuationToken = `
            [System.Web.HttpUtility]::`
            UrlDecode($usageData.NextLink.Split("=")[-1])

    } else {

        $continuationToken = ""

    }
} until (!$continuationToken)


# 課金レートの基になる情報を REST APIから取得(今回は従量課金プランを利用)
$offerDurableID = "MS-AZR-0003p" #参照URL http://azure.microsoft.com/en-us/support/legal/offer-details/
$currency = "JPY"
$locale = "en-US"
$region = "JP"
$rateCardUri = "https://management.azure.com/subscriptions/$subscriptionId/providers/Microsoft.Commerce/RateCard?api-version=$apiVersion`&`$filter=OfferDurableId eq '$offerDurableID' and Currency eq '$currency' and Locale eq '$locale' and RegionInfo eq '$region'"
$rateCardData = Invoke-RestMethod `
        -Uri $rateCardUri `
        -Method Get `
        -Headers $requestHeader `
        -ContentType $contentType


#リソース利用状況と課金レートから価格kを計算
$calculatedData = @()
foreach($data in $vmUsageData)
{
    $rateInfo = $rateCardData.Meters | 
        where{
            ($_.MeterName -eq $data.meterName) -and 
            ($_.MeterCategory -eq $data.meterCategory) -and 
            ($_.MeterSubCategory -eq $data.meterSubCategory) -and
            ($_.Unit -eq $data.unit)
            }
    
    $price = 0
    if($rateInfo)
    {
        $rateData = $rateInfo | where{$_.MeterRegion -eq $data.meteredRegion}
        if(!$rateData)
        {
            $rateData = $rateInfo | where{!$_.MeterRegion}
        }
        $price = ($rateData.MeterRates.0) * $data.quantity
    }
    $calculatedData += $data |
        Add-Member -NotePropertyName MeterRates -NotePropertyValue ($rateData.MeterRates.0) -PassThru |
        Add-Member -NotePropertyName Price -NotePropertyValue $price -PassThru 

}

# GridViewに出力
$calculatedData | Out-GridView