How to check an object is not empty with azure policy

IZMAR Mohamed (CSC/MST) 6 Reputation points
2023-07-07T14:28:53.6766667+00:00

Hello,

I am trying to make a policy to deny to deploy an AKS in case of the node label is not provided or empty

Thanks in advance for your help

This is my policy :

                "allOf": [
                  {
                    "field": "type",
                    "equals": "Microsoft.ContainerService/managedClusters"
                  },
                  {
                    "count": {
                      "field": "Microsoft.ContainerService/managedClusters/agentPoolProfiles[*]",
                      "where": {
                        "allOf": [
                          {
                            "field": "Microsoft.ContainerService/managedClusters/agentPoolProfiles[*].nodelabels",
                            "exists": "true"
                          },
                          {
    "value": "[indexOf(string(field('nodelabels')), '\"\"')]",
                            "Equals": ""

                          }
                        ]
                      }
                    },
                    "greater": 0
                  }
                ]
Azure Policy
Azure Policy
An Azure service that is used to implement corporate governance and standards at scale for Azure resources.
1,014 questions
0 comments No comments
{count} votes

2 answers

Sort by: Most helpful
  1. Ryan Hill 30,281 Reputation points Microsoft Employee Moderator
    2023-07-07T17:26:01.1833333+00:00

    Creating a deny Azure Policy for missing node labels on an AKS deployment, all you should really need to do is modify the "greater" operator to "equals" and change "value" to 0.

    {
      "mode": "All",
      "policyRule": {
        "if": {
          "allOf": [
            {
              "field": "type",
              "equals": "Microsoft.ContainerService/managedClusters"
            },
            {
              "count": {
                "field": "Microsoft.ContainerService/managedClusters/agentPoolProfiles[*]",
                "where": {
                  "anyOf": [
                    {
                      "field": "Microsoft.ContainerService/managedClusters/agentPoolProfiles[*].nodeLabels",
                      "exists": "false"
                    },
                    {
                      "value": "string(field('Microsoft.ContainerService/managedClusters/agentPoolProfiles[*].nodeLabels'))]",
                      "equals": "[[{}]"
                    }
                  ]
                }
              },
              "notEquals": 0
            }
          ]
        },
        "then": {
          "effect": "deny"
        }
      },
      "parameters": {}
    }
    

    EDIT 2023 July 14 @IZMAR Mohamed (CSC/MST) I know you've opened a support request for this issue. To benefit the broader community, I'm updating my answer above to reflect the policy that successfully checks for empty nodes.


  2. Tiago Furtado Goncalves 0 Reputation points Microsoft Employee
    2023-07-17T10:02:02.06+00:00

    Hi All,

    I'm adding here an eventual solution to this.

    Note this is a mere suggestion on how to create a set of policies that cover scenarios described, note sure if any changes on Azure/AKS ARM end could break functionality of these in the future.

    Essentially there are 2 scenarios to cover.

    First - Creation of AKS cluster must have Node Labels

    Policy checks if,

    1. Type is of “Managed Clusters”
    2. Count for node labels is not equals to ‘0’ (zero) – Counts if,
      1. “Node Labels” field from a node pool doesn’t exist on incoming ARM template
        1. “Node Labels” field from a node pool is empty on incoming ARM template

     And denies Cluster creation if Count for node labels is not equals to ‘0’ (zero)

    Adding some explanation to how point 2.b) is working, since is the one that seems to be giving the most headaches, please understand that we have taken a look into ARM templates that are generate when az cli commands for cluster creation are executed,

    Example,

    $ az aks create -g $RSG -n $AKS_NAME -c 1 --nodepool-labels "" --debug

    img1

    And found that “nodeLabels” field from an “agentPoolProfiles” object is filled with “{}”. Since “nodeLabels” field is an array/list the direct string you will find when empty will be “[{}]”.

    Then due to how Language used by Policies works we need to escape “[” character by adding another “[“ before, otherwise it will be read as a different directive.

    {
      "mode": "All",
      "policyRule": {
        "if": {
          "allOf": [
            {
              "field": "type",
              "equals": "Microsoft.ContainerService/managedClusters"
            },
            {
              "count": {
                "field": "Microsoft.ContainerService/managedClusters/agentPoolProfiles[*]",
                "where": {
                  "anyOf": [
                    {
                      "field": "Microsoft.ContainerService/managedClusters/agentPoolProfiles[*].nodeLabels",
                      "exists": "false"
                    },
                    {
                      "value": "[string(field('Microsoft.ContainerService/managedClusters/agentPoolProfiles[*].nodeLabels'))]",
                      "equals": "[[{}]"
                    }
                  ]
                }
              },
              "notEquals": 0
            }
          ]
        },
        "then": {
          "effect": "deny"
        }
      },
      "parameters": {}
    }
    

    Second - Node Pools being added must have Node Labels

    Policy checks if,

    1. “Node Label” does not exists
    2. Value of “nodeLabel” field from a node pool is empty on incoming ARM template

    And denies Node Pool creation/Addition when one any od above conditions is meet (i.e. is True)

    On point 2) we check if value is equal to “{}”.

    {
      "mode": "All",
      "policyRule": {
        "if": {
          "anyOf": [
            {
              "not": {
                "field": "Microsoft.ContainerService/managedClusters/agentPools/nodeLabels",
                "exists": "true"
              }
            },
            {
              "value": "[string(field('Microsoft.ContainerService/managedClusters/agentPools/nodeLabels'))]",
              "equals": "{}"
            }
          ]
        },
        "then": {
          "effect": "deny"
        }
      },
      "parameters": {}
    }
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.