Showcase Friday – Få oversikt over dine Azure ressurser med Power BI
Data Sources

I Episode 01 av Showcase Friday gikk vi igjennom hvordan  hente ut data fra Azure og bruke dataene som grunnlag for rapporter og dashbords i PowerBI.  I denne posten går vi igjennom hvilke data kilder som ble brukt til å hente ut data. Eksempel på hvordan tilkobling kan gjøres ved bruk av Power Query Formula Language “M” er lagt til hver data kilde.
Følgende Azure API ble brukt:

  • Azure Resource Management API
  • Azure Resource Usage API (Preview)
  • Azure Resource RateCard (Preview)

Rettigheter i Azure

For å få tilgang til å hente ut data, må kontoen som autentiseres ha “Read”  rettigheter på ressurser i azure. Role-Based Access Control (RBAC) kan brukes for å sette riktig tilgang.  Følg oppskriften for å delegere rettigheter.
https://docs.microsoft.com/en-us/azure/active-directory/role-based-access-control-configure

 Web Connector
Alle data kildene er API baserte så data vil bli hentet ved bruk av PowerBI WEB connector (http requests).
Web connectoren i PowerBI kjører http requests til API kilden, URL må legges til i connectoren. Svaret tilbake er i JASON format, så viktig at [Open file as JASON] er valgt.

  Untitled   2017-02-01_1544

Azure Resource Management API

ARM API’et gir deg mulighet til å hente ut ressurser, tags, ressursgrupper, datasenter lokasjoner, konfigurasjoner og mye mer.
Et godt tips er å gjøre seg kjent med hvordan API’et er bygget opp. Ved å logge  på resources.azure.com, kan du grafisk se hvordan API’et er bygget opp og hvilke ressurser som er tatt i bruk i subscription. I strukturen får man en god oversikt over hvordan man kan hente ut de forskjellige kategoriene. Explorer-en gir deg den eksakte GET spørringen du trenger fr å hente ut den bestemte provideren.

2017-02-01_1522

Eksempel Power Query kode
let
Source = Json.Document(Web.Contents(#”https://management.azure.com/subscriptions/SubscriptionID/providers/Microsoft.Compute/virtualMachines?api-version=2016-03-30“)),
value = Source[value],
#”Converted to Table” = Table.FromList(value, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
#”Expanded Column1″ = Table.ExpandRecordColumn(#”Converted to Table”, “Column1”, {“properties”, “type”, “location”, “tags”, “id”, “name”}, {“Column1.properties”, “Column1.type”, “Column1.location”, “Column1.tags”, “Column1.id”, “Column1.name”}),
#”Expanded Column1.properties” = Table.ExpandRecordColumn(#”Expanded Column1″, “Column1.properties”, {“diagnosticsProfile”, “hardwareProfile”, “networkProfile”, “osProfile”, “provisioningState”, “storageProfile”, “vmId”}, {“Column1.properties.diagnosticsProfile”, “Column1.properties.hardwareProfile”, “Column1.properties.networkProfile”, “Column1.properties.osProfile”, “Column1.properties.provisioningState”, “Column1.properties.storageProfile”, “Column1.properties.vmId”}),
#”Expanded Column1.properties.diagnosticsProfile” = Table.ExpandRecordColumn(#”Expanded Column1.properties”, “Column1.properties.diagnosticsProfile”, {“bootDiagnostics”}, {“Column1.properties.diagnosticsProfile.bootDiagnostics”}),
#”Expanded Column1.properties.diagnosticsProfile.bootDiagnostics” = Table.ExpandRecordColumn(#”Expanded Column1.properties.diagnosticsProfile”, “Column1.properties.diagnosticsProfile.bootDiagnostics”, {“enabled”, “storageUri”}, {“Column1.properties.diagnosticsProfile.bootDiagnostics.enabled”, “Column1.properties.diagnosticsProfile.bootDiagnostics.storageUri”}),
#”Expanded Column1.properties.hardwareProfile” = Table.ExpandRecordColumn(#”Expanded Column1.properties.diagnosticsProfile.bootDiagnostics”, “Column1.properties.hardwareProfile”, {“vmSize”}, {“Column1.properties.hardwareProfile.vmSize”}),
#”Expanded Column1.properties.networkProfile” = Table.ExpandRecordColumn(#”Expanded Column1.properties.hardwareProfile”, “Column1.properties.networkProfile”, {“networkInterfaces”}, {“Column1.properties.networkProfile.networkInterfaces”}),
#”Expanded Column1.properties.networkProfile.networkInterfaces” = Table.ExpandListColumn(#”Expanded Column1.properties.networkProfile”, “Column1.properties.networkProfile.networkInterfaces”),
#”Expanded Column1.properties.networkProfile.networkInterfaces1″ = Table.ExpandRecordColumn(#”Expanded Column1.properties.networkProfile.networkInterfaces”, “Column1.properties.networkProfile.networkInterfaces”, {“id”}, {“Column1.properties.networkProfile.networkInterfaces.id”}),
#”Expanded Column1.properties.osProfile” = Table.ExpandRecordColumn(#”Expanded Column1.properties.networkProfile.networkInterfaces1″, “Column1.properties.osProfile”, {“adminUsername”, “computerName”, “secrets”, “windowsConfiguration”}, {“Column1.properties.osProfile.adminUsername”, “Column1.properties.osProfile.computerName”, “Column1.properties.osProfile.secrets”, “Column1.properties.osProfile.windowsConfiguration”}),
#”Expanded Column1.properties.osProfile.secrets” = Table.ExpandListColumn(#”Expanded Column1.properties.osProfile”, “Column1.properties.osProfile.secrets”),
#”Expanded Column1.properties.osProfile.windowsConfiguration” = Table.ExpandRecordColumn(#”Expanded Column1.properties.osProfile.secrets”, “Column1.properties.osProfile.windowsConfiguration”, {“enableAutomaticUpdates”, “provisionVMAgent”}, {“Column1.properties.osProfile.windowsConfiguration.enableAutomaticUpdates”, “Column1.properties.osProfile.windowsConfiguration.provisionVMAgent”}),
#”Expanded Column1.properties.storageProfile” = Table.ExpandRecordColumn(#”Expanded Column1.properties.osProfile.windowsConfiguration”, “Column1.properties.storageProfile”, {“dataDisks”, “imageReference”, “osDisk”}, {“Column1.properties.storageProfile.dataDisks”, “Column1.properties.storageProfile.imageReference”, “Column1.properties.storageProfile.osDisk”}),
#”Expanded Column1.properties.storageProfile.dataDisks” = Table.ExpandListColumn(#”Expanded Column1.properties.storageProfile”, “Column1.properties.storageProfile.dataDisks”),
#”Expanded Column1.properties.storageProfile.imageReference” = Table.ExpandRecordColumn(#”Expanded Column1.properties.storageProfile.dataDisks”, “Column1.properties.storageProfile.imageReference”, {“offer”, “publisher”, “sku”, “version”}, {“Column1.properties.storageProfile.imageReference.offer”, “Column1.properties.storageProfile.imageReference.publisher”, “Column1.properties.storageProfile.imageReference.sku”, “Column1.properties.storageProfile.imageReference.version”}),
#”Expanded Column1.properties.storageProfile.osDisk” = Table.ExpandRecordColumn(#”Expanded Column1.properties.storageProfile.imageReference”, “Column1.properties.storageProfile.osDisk”, {“caching”, “createOption”, “name”, “osType”, “vhd”}, {“Column1.properties.storageProfile.osDisk.caching”, “Column1.properties.storageProfile.osDisk.createOption”, “Column1.properties.storageProfile.osDisk.name”, “Column1.properties.storageProfile.osDisk.osType”, “Column1.properties.storageProfile.osDisk.vhd”}),
#”Expanded Column1.properties.storageProfile.osDisk.vhd” = Table.ExpandRecordColumn(#”Expanded Column1.properties.storageProfile.osDisk”, “Column1.properties.storageProfile.osDisk.vhd”, {“uri”}, {“Column1.properties.storageProfile.osDisk.vhd.uri”}),
#”Utvidet Column1.tags” = Table.ExpandRecordColumn(#”Expanded Column1.properties.storageProfile.osDisk.vhd”, “Column1.tags”, {“Department”, “Environment”}, {“Department”, “Environment”})
in
#”Utvidet Column1.tags”

For mer detaljer om Azure Resource Management API:
https://docs.microsoft.com/en-us/rest/api/resources/

Azure Resource Usage API (Preview)

API’et blir brukt for å hente ut forbruk for de ressursene som er blitt “kjøpt / er i bruk”.  API’et gir mulighet for å sette en bestemt tidsinnterval som data kan hentes ut fra. På den måten kan man begrense mengden data som hentes ned.

Følgende parametere kan endres i URL for å få mer eller mindre detaljert informasjon ( makert med rødt).

  • Start and end date/time
  • Aggregation granularity (ie: daily, hourly)
  • Instance level detail (ie: for multiple instances of the same resource)

Eksempel Power Query kode
let

Source = Json.Document(Web.Contents(“https://management.azure.com/subscriptions/SubscriptionID/providers/Microsoft.Commerce/UsageAggregates?api-version=2015-06-01-preview&reportedStartTime=2016-10-1T00%3a00%3a00%2b00%3a00&reportedEndTime=2016-12-12T00%3a00%3a00%2b00%3a00&aggregationGranularity=Daily&showDetails=false“)),
value = Source[value],
#”Converted to Table” = Table.FromList(value, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
#”Expanded Column1″ = Table.ExpandRecordColumn(#”Converted to Table”, “Column1”, {“id”, “name”, “type”, “properties”}, {“id”, “name”, “type”, “properties”}),
#”Expanded properties” = Table.ExpandRecordColumn(#”Expanded Column1″, “properties”, {“subscriptionId”, “usageStartTime”, “usageEndTime”, “meterName”, “meterCategory”, “meterSubCategory”, “unit”, “instanceData”, “meterId”, “infoFields”, “quantity”}, {“properties.subscriptionId”, “properties.usageStartTime”, “properties.usageEndTime”, “properties.meterName”, “properties.meterCategory”, “properties.meterSubCategory”, “properties.unit”, “properties.instanceData”, “properties.meterId”, “properties.infoFields”, “properties.quantity”})
in
#”Expanded properties”

2017-02-02_0952

For mer detaljer om Azure Resource Usage API (Preview)
https://msdn.microsoft.com/en-us/library/azure/mt219003.aspx
https://msdn.microsoft.com/en-us/library/azure/mt219001.aspx

Azure Resource RateCard (Preview)

Prisene for tjenester i Azure endrer seg og azure resource ratecard api, gir muligheter for å hente ned siste pris oversikt og  detaljer. Det finnes opp mot 25 forskjellige offers i Azure, så riktig azure OfferDurableId  må legges inn i URL for å finne riktig pris og detaljer.

For å finne riktig ID kan man logge inn på portal.azure.com -> [Subscriptions] under detaljer finner du OfferID.

2017-02-02_0938

Ved å legge inn Currency eq ‘NOK‘ and Locale eq ‘nb-NO‘ and RegionInfo eq ‘NO, blir verdiene satt til norsk.

Eksempel Power Query kode
let
Source = Json.Document(Web.Contents(“https://management.azure.com/subscriptions/3a1a103c-2b02-4450-82ae-0c485bffafd5/providers/Microsoft.Commerce/RateCard?api-version=2016-08-31-preview&$filter=OfferDurableId eq ‘MS-AZR-0064P‘ and Currency eq ‘NOK‘ and Locale eq ‘nb-NO‘ and RegionInfo eq ‘NO‘ “)),
#”Converted to Table” = Record.ToTable(Source),
Value = #”Converted to Table”{1}[Value],
#”Converted to Table1″ = Table.FromList(Value, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
#”Expanded Column1″ = Table.ExpandRecordColumn(#”Converted to Table1″, “Column1”, {“MeterId”, “MeterName”, “MeterCategory”, “MeterSubCategory”, “Unit”, “MeterTags”, “MeterRegion”, “MeterRates”, “EffectiveDate”, “IncludedQuantity”, “MeterStatus”}, {“MeterId”, “MeterName”, “MeterCategory”, “MeterSubCategory”, “Unit”, “MeterTags”, “MeterRegion”, “MeterRates”, “EffectiveDate”, “IncludedQuantity”, “MeterStatus”}),
#”Expanded MeterTags” = Table.ExpandListColumn(#”Expanded Column1″, “MeterTags”),
#”Expanded MeterRates” = Table.ExpandRecordColumn(#”Expanded MeterTags”, “MeterRates”, {“0”}, {“MeterRates.0”})
in
#”Expanded MeterRates”

2017-02-02_0947

Relasjonen mellom Ratecard data og Usage data ligger i [MeterID].

2017-02-02_0957

For mer detaljer om Azure Resource RateCard (Preview)
https://msdn.microsoft.com/en-us/library/azure/mt219005.aspx
https://msdn.microsoft.com/en-us/library/azure/mt219004.aspx

Fredrik Knalstad

Author Fredrik Knalstad

More posts by Fredrik Knalstad

Leave a Reply