DEV Community

Owen Davies
Owen Davies

Posted on • Originally published at owendavies.net on

Get latest Azure API Version in ARM templates

The following script will crawl through all your ARM templates in a folder and check for the latest Azure API version.

This is useful if you want to make sure you are staying up to date with the latest API.

Currently there is no way to be notified if your ARM templates have a newer version of the API. And if you are anything like me you have hundreds of nested ARM templates to keep up to date. Keeping track of all the resources you are using in all your files is difficult.

This will take into account if you hold your resource API versions inside variables, parameters or directly in the apiVersion itself.

Examples of where it looks

I store Resource API versions in multiple places depending on a few different reasons in my ARM templates. I try to store in Variables as much as possible for reuse, but often I need to store in parameters so that I can pass in to a nested template.

The following JSON ARM Template file has examples of storing the API version in 3 places:

  1. Directly in the resource
  2. In Variables
  3. In Parameters
{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "apiVersionDisks": "2017-06-01"
  },
  "variables": {
    "apiVersionResourcesDeployment": "2017-05-10",
    "apiVersionDisks": "2017-04-01",
    "apiVersionStorage": "2017-04-01"
  },
  "resources": [{
      "apiVersion": "[variables('apiVersionResourcesDeployment')]",
      "type": "Microsoft.Resources/deployments"
    },
    {
      "name": "Name1",
      "type": "Microsoft.Storage/storageAccounts",
      "apiVersion": "[variables('apiVersionStorage')]",
    },
    {
      "name": "Name1",
      "type": "Microsoft.Compute/disks",
      "apiVersion": "[parameters('apiVersionDisks')]",
    },
    {
      "name": "Name1",
      "type": "Microsoft.Compute/disks",
      "apiVersion": "2015-06-15",
    }
  ]
}

The Script!

This script will check all 3 locations for API versions to check against.

$templatePath = 'C:\YOUR\ARM\PATH'

$listOfResources = @()

Get-ChildItem $templatePath -Recurse -Filter *.json |
Foreach-Object {

    $content = (Get-Content $_.FullName | ConvertFrom-Json)

    foreach($resource in $content.resources)
    {
        $resourceObject = New-Object -TypeName pscustomobject -Property @{
            "fileName" = $_.FullName
            "resourceName" = $($resource.type)
            "apiVersion" = ""
            "apiVersionVariableName" = ""
            "apiVersionParameterName" = ""
            "latestApiVersion" = ""
        }

        if($($resource.apiVersion) -like '*variables*')
        {
            $apiVariable = ($resource.apiVersion).replace("[variables('","").replace("')]","")

            $resourceObject.apiVersionVariableName = $apiVariable
            $resourceObject.apiVersion = $($($content.variables).$apiVariable)
        }
        elseif($resource.apiVersion -like '*parameters*')
        {
            $apiVariable = ($resource.apiVersion).replace("[parameters('","").replace("')]","")

            $apiParameter = ($resource.apiVersion).replace("[parameters('","").replace("')]","")

            $resourceObject.apiVersionParameterName = $apiParameter
            $resourceObject.apiVersion = $($($content.parameters).$apiParameter)
        }
        else
        {
            $resourceObject.apiVersion = $($resource.apiVersion)
        }

        $listOfResources += $resourceObject
    }
}

$resources = $listOfResources.resourceName | Sort-Object | Get-Unique

Foreach($i in $resources)
{   
    $providerNamespace,$resourceTypeName = $i.split("/",2)
    $latestApiVersion = ((Get-AzureRmResourceProvider -ProviderNamespace $providerNamespace).ResourceTypes | Where-Object ResourceTypeName -eq $resourceTypeName).ApiVersions | select -First 1

    $editObj = $listOfResources | where {$_.resourceName -eq $i}
    foreach($r in $editObj)
    {
        $r.latestApiVersion=$latestApiVersion   
    }

}

Foreach($resource in $listOfResources)
{
    if($resource.latestApiVersion -ne $resources.apiVersion)
    {
        Write-Host "`nThere is a new ApiVersion for $($resource.resourceName)"
        Write-Host "Filename: [$($resource.fileName)]"
        Write-Host "Current ApiVersion: [$($resource.apiVersion)]"
        Write-Host "Latest ApiVersion: [$($resource.latestApiVersion)]"
    }
}

Please let me know if you’ve found this useful! :-)

Top comments (0)