Mallow
Azure Tips · 12. huhtikuuta 2024

Azure Change Analysis – etsi syy, joka rikkoi sovelluksesi

Majid Maskati

Kirjoittaja: Majid Maskati

Azure Change Analysis – etsi syy, joka rikkoi sovelluksesi

Azure Change Analysisin käyttäminen infrastruktuurimuutosten seurantaan.

Azure Change Analysis parantaa Azure-resursseihin tehtyjen muutosten näkyvyyttä. Se seuraa muutoksia tilaustasolla ja tallentaa ne Azure Resource Graphin resourcechanges-tauluun.

Maaliskuusta 2024 lähtien muutosseuranta sisältää myös tarkempia tietoja siitä, kuka muutoksen teki ja miten. Mukana on esimerkiksi tekijän identiteetti, client type (Azure Portal, Azure CLI, ARM template) sekä operaatio, joka johti muutokseen (esim. Microsoft.Web/sites/write). Käytännössä sinun ei aina tarvitse kaivaa Activity Logia erikseen. Samat tiedot löytyvät Change Analysisista.

resourcechanges-taulun rakenne ei ole erityisen selkeä, jos haluat nähdä muutokset nopeasti yhdellä silmäyksellä. Alla oleva Azure Resource Graph -kysely “tiivistää” muutostiedot helpommin luettavaan taulukkomuotoon.

  • resourceChangeType kertoo, onko kyseessä resurssin create, update vai delete
  • Päivityksissä propertyChangeType kertoo, onko ominaisuus insert, update vai remove
  • propertyName sekä siihen liittyvät previousValue ja newValue
  • changedBy kertoo tekijän nimen tai object id:n
  • operation on ARM-operaatio, joka johti muutokseen
  • correlationId auttaa hakemaan liittyviä tapahtumia Activity Logista
  • activityLogLink on linkki Azure Portalin Activity Logiin. Se on esisuodatettu korrelaatiotunnuksella ja aikaleimalla.
resourcechanges
| extend timestamp = todatetime(properties.changeAttributes.timestamp)
| extend changedBy = tostring(properties.changeAttributes.changedBy)
| extend clientType = tostring(properties.changeAttributes.clientType)
| extend operation = tostring(properties.changeAttributes.operation)
| extend correlationId = tostring(properties.changeAttributes.correlationId)
| extend resourceChangeType = tostring(properties.changeType)
| extend targetResourceId = properties.targetResourceId
| parse targetResourceId with '/subscriptions/' subscriptionId '/resourceGroups/' resourceGroup '/providers/' resourceProvider '/' resourceType '/' resource
| extend resourceProviderType = strcat(resourceProvider, '/', resourceType)
| extend activityLogQuery = strcat('{"query":{"subscriptions":["', subscriptionId, '"],"searchString":"', correlationId, '","timeSpan":"3","startTime":"', replace(' ', 'T', format_datetime(timestamp - 3h, 'yyyy-MM-dd HH:mm:ss.fff')), 'Z","endTime":"', replace(' ', 'T', format_datetime(timestamp + 3h, 'yyyy-MM-dd HH:mm:ss.fff')), 'Z"}}')
| extend activityLogLink = iff(correlationId=='00000000-0000-0000-0000-000000000000', '-', strcat('https://portal.azure.com/#view/Microsoft_Azure_ActivityLog/ActivityLogBlade/queryInputs~/', url_encode_component(activityLogQuery)))
| extend changes = iff(array_length(bag_keys(properties.changes))==0, dynamic({'-':dynamic({'propertyChangeType':'-'})}), properties.changes)
| mv-expand propertyName = bag_keys(changes) to typeof(string)
| extend propertyChangeType = tostring(changes[propertyName].propertyChangeType)
| extend previousValue = coalesce(changes[propertyName].previousValue, '-')
| extend newValue = coalesce(changes[propertyName].newValue, '-')
| sort by timestamp, subscriptionId, resourceGroup, resourceProviderType, resource, resourceChangeType, propertyChangeType, propertyName
| project timestamp, subscriptionId, resourceGroup, resourceProviderType, resource, resourceChangeType, propertyChangeType, propertyName, previousValue, newValue, operation, changedBy, clientType, correlationId, activityLogLink