microsoft / PSRule

Validate infrastructure as code (IaC) and objects using PowerShell rules.
https://microsoft.github.io/PSRule/v2/
MIT License
392 stars 49 forks source link

Ability to exclude rules by tag / pillars #1825

Open o-l-a-v opened 4 months ago

o-l-a-v commented 4 months ago

Is your feature request related to a problem? Please describe.

I'd like the ability to exclude pillars / group of rules by category. Take PSRule.Rules.Azure for instance, where I'd like to exclude all rules in the pillar "reliability".

Example rule in this pillar / category:

Seems it has tag 'Azure.WAF/pillar' = 'Reliability'.

Describe the solution you'd like

The ability to exclude a group of rules based on pillar / category.

Describe alternatives you've considered

Invoke-PSRule -Module 'PSRule.Rules.Azure' -Option @{
    'AZURE_BICEP_CHECK_TOOL'             = [bool] $true
    'AZURE_BICEP_FILE_EXPANSION'         = [bool] $true
    'AZURE_BICEP_FILE_EXPANSION_TIMEOUT' = [uint16] 30
    'AZURE_BICEP_PARAMS_FILE_EXPANSION'  = [bool] $true
    'RULE.EXCLUDE'                       = [string[]](
        (Get-PSRule -Module 'PSRule.Rules.Azure').Where{$_.'Tags'.'Azure.WAF/pillar' -eq 'Reliability'}.'Name'
    )
}

Additional context

o-l-a-v commented 4 months ago

My first workaround made PSRule throw an error:

TargetSite     : System.String ToJson(System.Object[], System.Nullable`1[System.Int32])
Message        : Index was outside the bounds of the array.
Data           : {[System.Management.Automation.Interpreter.InterpretedFrameInfo,
                 System.Management.Automation.Interpreter.InterpretedFrameInfo[]]}
InnerException : 
HelpLink       : 
Source         : Microsoft.PSRule.Core
HResult        : -2146233080
StackTrace     :    at PSRule.Pipeline.Output.JsonOutputWriter.ToJson(Object[] o, Nullable`1 jsonIndent) in
                 /_/src/PSRule/Pipeline/Output/JsonOutputWriter.cs:line 25
                    at PSRule.Pipeline.Output.JsonOutputWriter.Serialize(Object[] o) in
                 /_/src/PSRule/Pipeline/Output/JsonOutputWriter.cs:line 20
                    at PSRule.Pipeline.SerializationOutputWriter`1.End() in /_/src/PSRule/Pipeline/PipelineWriter.cs:line 432
                    at PSRule.Pipeline.InvokeRulePipeline.End() in /_/src/PSRule/Pipeline/InvokeRulePipeline.cs:line 98
                    at CallSite.Target(Closure, CallSite, Object)
                    at System.Management.Automation.Interpreter.DynamicInstruction`2.Run(InterpretedFrame frame)
                    at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)

So I'll do this instead:

## Get all available rules and find the ones to exclude
$PSRuleRulesAvailable = [array](Get-PSRule -Module 'PSRule.Rules.Azure')
$PSRuleRulesExclude   = [string[]](
    $PSRuleRulesAvailable.Where{
        $_.'Tags'.'Azure.WAF/pillar' -eq 'Reliability' -or
        $_.'Info'.'Annotations'.'severity' -eq 'Awareness'
    }.'Name' | Sort-Object
)

## Run PSRule
$PSRuleScan = [PSCustomObject[]](
    Invoke-PSRule -InputPath $FilePath -Module 'PSRule.Rules.Azure' -Outcome 'Fail','Error' -OutputFormat 'Json' -Option @{
        'AZURE_BICEP_CHECK_TOOL'             = [bool] $true
        'AZURE_BICEP_FILE_EXPANSION'         = [bool] $true
        'AZURE_BICEP_FILE_EXPANSION_TIMEOUT' = [uint16] 30
        'AZURE_BICEP_PARAMS_FILE_EXPANSION'  = [bool] $true
    } | ConvertFrom-Json | Where-Object -FilterScript {$_.'ruleName' -notin $PSRuleRulesExclude} | Sort-Object -Property 'ruleName'
)
BernieWhite commented 4 months ago

@o-l-a-v Thanks for the suggestion.

Another approach would be to define a custom baseline.

---
# Synopsis: A custom baseline without reliability
apiVersion: github.com/microsoft/PSRule/v1
kind: Baseline
metadata:
  name: MyBaseline
spec:
  rule:
    tag:
      release: GA
      Azure.WAF/pillar: [ 'Security', 'Cost Optimization', 'Performance Efficiency', 'Operational Excellence' ]

You can use the -Baseline for cmdlets or baseline: for GitHub Actions/ Azure Pipelines to specify the baseline.

See: