Search code examples
terraformopen-policy-agentrego

Open policy agent define dynamic global variable


I was wondering if there's any way to prettify my code as it looks terribly inefficient and totally not DRY. What I'm trying to achieve is to pull a specific resource out of a list of resources (a resource named "aks" out of a terraform plan), and run some tests against it. Problem is, I am using the some keyword to get it which prevents me from configuring a global variable, which causes a lot of repetition, for example:

aks_default_pool_type_vmss {
    some index
    input.planned_values.root_module.resources[index].type == "azurerm_kubernetes_cluster"
    aks := input.planned_values.root_module.resources[index]
    aks.values.default_node_pool[0].type == "VirtualMachineScaleSets"
}

aks_system_assigned_identity {
    some index
    input.planned_values.root_module.resources[index].type == "azurerm_kubernetes_cluster"
    aks := input.planned_values.root_module.resources[index]
    aks.values.identity[_].type == "SystemAssigned"
}

Is there any way to create a "global" variable which will catch the aks resource, in order to prevent all of the re-calculation?

Cheers.


Solution

  • You can create a rule who creates a set of aks objects (See generating sets in the OPA documentation):

    clusters[aks] {
        some index
        input.planned_values.root_module.resources[index].type == "azurerm_kubernetes_cluster"
        aks := input.planned_values.root_module.resources[index]
    }
    

    And then your rules can rewrite your to the following:

    aks_default_pool_type_vmss {
        aks := clusters[_]
        aks.values.default_node_pool[0].type == "VirtualMachineScaleSets"
    }
    
    aks_system_assigned_identity {
        aks := clusters[_]
        aks.values.identity[_].type == "SystemAssigned"
    }