azure-policy

How to audit for a minimum version of Python used in Azure app services?


Microsoft provides a builtin Azure policy to audit for Azure App Service apps that do not comply with a given Python version:

https://www.azadvertizer.net/azpolicyadvertizer/7008174a-fd10-4ef0-817e-fc820a951d73.html

However, this policy audits for the value of this field to equal a certain version, with a concatenated string that for example results in 'PYTHON|3.9'.

Microsoft.Web/sites/config/web.linuxFxVersion

However, I want the policy to audit for instances that are lower than the version specified.
So the policy requires to use at least version 3.9 or higher. Values lower than 3.9 should trigger the policy to audit/deny.

I tried to use the following logic within the existenceCondition, however with no luck (null value).
I would expect that, based on the split on the pipe ( | ) , the second item of the array ( [1] ) would result in the version (i.e. '3.9').

  {
    "value": "[split(field('Microsoft.Web/sites/config/web.linuxFxVersion'),'|')[1]]",
    "greaterOrEquals": "[parameters('LinuxPythonVersion')]"
  }

Solution

  • After some testing and fiddling around with nested template function expressions, this existence condition seems to work well. Basically what it does, is converting the version (i.e. 3.8) to a number with 3 positions (3.8 becomes 308, 3.11 becomes 311, etc.). The same expression is applied to the input parameter so both the input parameter and the actual version are compared in the same format. This allows us to use the 'greaterOrEquals' condition.

        "existenceCondition": {
          "anyOf": [
            {
              "field": "Microsoft.Web/sites/config/web.linuxFxVersion",
              "notContains": "PYTHON"
            },
            {
              "value": "[concat(substring(split(field('Microsoft.Web/sites/siteConfig.linuxFxVersion'), '|')[1], 0, 1), if(equals(length(split(split(field('Microsoft.Web/sites/siteConfig.linuxFxVersion'), '|')[1], '.')[1]), 1), concat('0', split(split(field('Microsoft.Web/sites/siteConfig.linuxFxVersion'), '|')[1], '.')[1]), split(split(field('Microsoft.Web/sites/siteConfig.linuxFxVersion'), '|')[1], '.')[1]))]",
              "greaterOrEquals": "[concat(substring(parameters('LinuxPythonMinimumVersion'), 0, 1), if(equals(length(split(parameters('LinuxPythonMinimumVersion'), '.')[1]), 1), concat('0', split(parameters('LinuxPythonMinimumVersion'), '.')[1]), split(parameters('LinuxPythonMinimumVersion'), '.')[1]))]"
            }
          ]
        }