Azure / PSRule.Rules.Azure

Rules to validate Azure resources and infrastructure as code (IaC) using PSRule.
https://azure.github.io/PSRule.Rules.Azure/
MIT License
386 stars 84 forks source link

Generating rule for VM extensions from policy is incorrect #2608

Closed bbz94 closed 6 months ago

bbz94 commented 8 months ago

I try to use Azure policy assignment data as a rule to check a specific Azure subscription for a compliance

I use the following script:

$outputPath = "$ENV:temp"
$scope = '/providers/Microsoft.Management/managementGroups/mgName'
$targetSubId = 'nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn'

$azPolicyAssignmentData = Export-AzPolicyAssignmentData -Scope $scope -OutputPath $outputPath
$azPolicyAssignmentRuleData = Export-AzPolicyAssignmentRuleData -AssignmentFile $($azPolicyAssignmentData.fullname) -OutputPath "$outputPath\custom-rules"

$context = Set-AzContext -SubscriptionId $targetSubId
$azRuleData = Export-AzRuleData -Subscription $($context.subscription.name) -OutputPath $outputPath

Set-Location $outputPath
$option = New-PSRuleOption -Option @{ 'Rule.includeLocal' = 'true' }
Assert-PSRule -Path 'custom-rules' `
    -InputPath $($azRuleData.FullName) `
    -OutputPath "$outputPath\output.json" `
    -OutputFormat Json `
    -Option $option

It always returns that nothing has been found: Rules processed: 0, failed: 0, errored: 0 Run 1f66aa572d21c03466f67dcd55b89abba6f3abbc5153ee9cd912f4c54c529a83cf453caea2e5252f9f9fcb674778da9c8bc7fccf5f648afeace3f11134be9637 completed in 00:00:01.4179711 OperationStopped: Index was outside the bounds of the array.

Module versions: Version Name


2.9.0 PSRule 1.31.3 PSRule.Rules.Azure

For testing purpose: I exported Azure Policy Assignment data for a specific target subscription and then tried to run "Assert-PSRule" against the same Azure subscription. Result always is "Rules processed: 0, failed: 0, errored: 0" From Azure Policies blade I clearly see that there are compliant and non compliant policies.

Am I missing something?

BernieWhite commented 8 months ago

@bbz94 There could be a bug here, but first try setting binding option because this is required with any custom rules. https://microsoft.github.io/PSRule/v2/concepts/PSRule/en-US/about_PSRule_Options/#bindingtargettype

You add this to ps-rule.yaml but to add it to you command line:

$outputPath = "$ENV:temp"
$scope = '/providers/Microsoft.Management/managementGroups/mgName'
$targetSubId = 'nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn'

$azPolicyAssignmentData = Export-AzPolicyAssignmentData -Scope $scope -OutputPath $outputPath
$azPolicyAssignmentRuleData = Export-AzPolicyAssignmentRuleData -AssignmentFile $($azPolicyAssignmentData.fullname) -OutputPath "$outputPath\custom-rules"

$context = Set-AzContext -SubscriptionId $targetSubId
$azRuleData = Export-AzRuleData -Subscription $($context.subscription.name) -OutputPath $outputPath

Set-Location $outputPath
$option = New-PSRuleOption -Option @{ 'Rule.includeLocal' = 'true'; 'Binding.TargetType' = 'resourceType', 'type' }
Assert-PSRule -Path 'custom-rules' `
    -InputPath $($azRuleData.FullName) `
    -OutputPath "$outputPath\output.json" `
    -OutputFormat Json `
    -Option $option

If you're still getting an exception, can you start with:

bbz94 commented 8 months ago

@BernieWhite

I tried with:

$option = New-PSRuleOption -Option @{ 'Rule.includeLocal' = 'true'; 'Binding.TargetType' = 'resourceType', 'type' }

I still receive the following output: Rules processed: 0, failed: 0, errored: 0

I verified that rule files do exist in custom-rules folder (In total 307 rules):

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---          18.12.2023    10:26         377976 definitions-export-439de130.Rule.jsonc

Any ideas why it does not work?

BernieWhite commented 8 months ago

@bbz94 your process seems fine. Are you able to share your .Rule.jsonc.

bbz94 commented 8 months ago

@BernieWhite I will not share the whole file but I can share one of the rules:

  [
    {
        // Synopsis: The Guest Configuration extension requires a system assigned managed identity. Azure virtual machines in the scope of this policy will be non-compliant when they have the Guest Configuration extension installed but do not have a system assigned managed identity. Learn more at https://aka.ms/gcpol
        "apiVersion": "github.com/microsoft/PSRule/v1",
        "kind": "Rule",
        "metadata": {
            "name": "Azure.Policy.eba3fd518936",
            "displayName": "Virtual machines' Guest Configuration extension should be deployed with system-assigned managed identity",
            "tags": {
                "Azure.Policy/category": "Security Center"
            },
            "annotations": {
                "Azure.Policy/id": "/providers/Microsoft.Authorization/policyDefinitions/d26f7642-7545-4e18-9b75-8c9bbdee3a9a",
                "Azure.Policy/version": "1.0.1"
            }
        },
        "spec": {
            "recommend": "The Guest Configuration extension requires a system assigned managed identity. Azure virtual machines in the scope of this policy will be non-compliant when they have the Guest Configuration extension installed but do not have a system assigned managed identity. Learn more at https://aka.ms/gcpol",
            "type": [
                "Microsoft.Compute/virtualMachines/extensions"
            ],
            "with": [
                "PSRule.Rules.Azure\\Azure.Policy.Indexed"
            ],
            "where": {
                "field": "properties.publisher",
                "equals": "Microsoft.GuestConfiguration"
            },
            "condition": {
                "field": "resources",
                "allOf": [
                    {
                        "field": "identity.type",
                        "contains": "SystemAssigned"
                    }
                ],
                "where": {
                    "allOf": [
                        {
                            "type": ".",
                            "equals": "Microsoft.Compute/virtualMachines"
                        },
                        {
                            "name": ".",
                            "equals": "[first(split(field('fullName'), '/'))]"
                        }
                    ]
                }
            }
        }
    }
]

I tried to "Assert-PSRule" using this one rule, and the result still is the same:

Rules processed: 0, failed: 0, errored: 0
Run 69f78c9bcdb405439e7eb8c32b66259a3d5a9282 completed in 00:00:01.0382695
OperationStopped: Index was outside the bounds of the array
BernieWhite commented 8 months ago

@bbz94 There looks to be a problem with how this rule is being generated. This is a bug. Thanks for reporting the issue.

Hard to say if this is the only cause of your issue, but this one would probably not run because it wouldn't match anything.

Running Assert-PSRule with -Verbose -Debug may give you further information that will help you troubleshooting this further.

The verbose output should show any rules that are detected and should evaluate for each azure resource.

bbz94 commented 6 months ago

@BernieWhite I'm still getting the same result with the latest module.

Name                            Version
----                            -------
PSRule                          3.0.0
PSRule.Rules.Azure              1.33.1

I'm using following script:

$azPolicyAssignmentData = Export-AzPolicyAssignmentData -Scope $scope -OutputPath $outputPath
$azPolicyAssignmentRuleData = Export-AzPolicyAssignmentRuleData -AssignmentFile $($azPolicyAssignmentData.fullname) -OutputPath "$outputPath\custom-rules"

$context = Set-AzContext -SubscriptionId $targetSubId
$azRuleData = Export-AzRuleData -Subscription $($context.subscription.name) -OutputPath $outputPath

Set-Location $outputPath
$option = New-PSRuleOption -Option @{ 'Rule.includeLocal' = 'true'; 'Binding.TargetType' = 'resourceType', 'type' }
$psRule = Assert-PSRule -Path 'custom-rules' `
    -InputPath $($azRuleData.FullName) `
    -OutputPath "$outputPath\output.json" `
    -OutputFormat Json `
    -Option $option

It generates following rules:

// Synopsis: Deploys the diagnostic settings for Key Vault to stream to a regional Log Analytics workspace when any Key Vault which is missing this diagnostic settings is created or updated.
"apiVersion":"github.com/microsoft/PSRule/v1","kind":"Rule","metadata":{"name":"Azure.Policy.5429c3cd4126","displayName":"Deploy Diagnostic Settings for Key Vault to Log Analytics workspace","tags":{"Azure.Policy/category":"Monitoring"},"annotations":{"Azure.Policy/id":"/providers/Microsoft.Authorization/policyDefinitions/bef3f64c-5290-43b7-85b0-9b254eef4c47","Azure.Policy/version":"3.0.0"}},"spec":{"recommend":"Deploys the diagnostic settings for Key Vault to stream to a regional Log Analytics workspace when any Key Vault which is missing this diagnostic settings is created or updated.","type":["Microsoft.KeyVault/vaults"],"with":["PSRule.Rules.Azure\\Azure.Policy.Indexed"],"condition":{"field":"resources","allOf":[{"allOf":[{"greaterOrEqual":1,"field":"properties.logs[*]","allOf":[{"field":"enabled","equals":"True"},{"field":"category","equals":"AuditEvent"}]},{"greaterOrEqual":1,"field":"properties.metrics[*]","allOf":[{"field":"enabled","equals":"False"}]},{"anyOf":[{"value":false,"equals":false},{"field":"properties.workspaceId","equals":"/subscriptions/a7adf67c-e781-4e8b-b4df-61d2c57f4ece/resourceGroups/rg-mgmt-p-weu-001/providers/Microsoft.OperationalInsights/workspaces/log-mgmt-p-weu-001"}]}]}],"where":{"allOf":[{"type":".","equals":"Microsoft.Insights/diagnosticSettings"},{"name":".","equals":"[parameters('profileName')]"}]}}}},{

I receive following error:

    ____  _____ ____        __
   / __ \/ ___// __ \__  __/ /__
  / /_/ /\__ \/ /_/ / / / / / _ \
 / ____/___/ / _, _/ /_/ / /  __/
/_/    /____/_/ |_|\__,_/_/\___/

Using PSRule v3.0.0-B0153

----------------------------
Explore documentation: https://aka.ms/ps-rule
Contribute and find source: https://github.com/microsoft/PSRule
Report issues: https://github.com/microsoft/PSRule/issues
----------------------------
   WARN  Target object '5b1956westus' has not been processed because no matching rules were found.
   WARN  Target object 'ado-webhooks-kv-prod' has not been processed because no matching rules were found.

Rules processed: 0, failed: 0, errored: 0
Run 11ea7a401de20d382ec734f1056cc9cb4bb2ac2bdeab2779b7cb683791de7bac5443af997e06052f377962f85de96584ec44a8800b64129d89b589a835cb71bb completed in 00:00:01.3090964     
OperationStopped: Index was outside the bounds of the array.

Any solution that would help? Your fix did not fix this problem.

Thank you in advance!

BernieWhite commented 6 months ago

Thanks @bbz94 I'll reopen the issue. I can see this is for a different reason, although the exception is the same.


Separate to that, the updated output doesn't seem to be including PSRule.Rules.Azure which is required for the policy rules to work, maybe add a -Module PSRule.Rules.Azure to your command line.

bbz94 commented 6 months ago

@BernieWhite -Module PSRule.Rules.Azure solved problem. Thanks.