In my previous article, Enhancing Bicep Module Testing with PSRule, we explored how to integrate PSRule into your DevOps pipeline to validate Bicep modules against Azure best practices. Building on that approach, this guide dives into custom PSRule rules, allowing you to simulate Azure Policy checks directly in your pipeline and add compliance pre-checks that align with organization-specific Azure Policies. This adds an additional layer of security and compliance to Bicep module testing in the CI/CD process.

This post builds on the foundation from How to Create and Test Bicep Modules for Azure Bicep Registry, where I discussed structuring Bicep modules, using Azure DevOps for deployments, and conducting initial validations. Together, these articles provide a comprehensive approach to Bicep module testing with enhanced compliance and policy alignment.

Why Use Custom Rules for PSRule?

PSRule offers a unique approach to IaC testing that complements language-specific linters like the Bicep linter or ARM-TTK. Whereas these linters focus on syntax and language correctness, PSRule is focused on how resources are configured and whether they align with best practices for security, governance, and efficiency.

  • Azure-Centric Rules: With the PSRule.Rules.Azure module, you can validate Bicep templates against over 430 predefined best practices from Microsoft. These rules are updated quarterly, ensuring alignment with the latest Azure standards.

  • Beyond Static Checks: By using custom PSRule rules, you add proactive compliance checks to validate Azure Policy rules before deployment, catching issues early. This helps enforce organization-specific policies, like required tags or resource limitations, before resources reach production.

  • Shift-Left Compliance: Adopting a Shift-Left approach in DevOps means catching issues earlier in the development lifecycle. PSRule enables this by focusing on resource configuration compliance rather than just syntax, helping prevent misconfigurations before they become costly.

PSRule’s flexibility also extends to custom rules for unique requirements, making it highly adaptable to your organization’s needs.

Configuring Custom Rules for PSRule

Step 1: Creating the ps-rule Directory and Custom Rules

  1. Set up the ps-rule Directory: Create a directory named ps-rule in your repository. This folder will house all our rules.
  2. Define Custom Rules: Create rules using .yaml or .Rule.ps1 files within the our ps-rule directory. Ensure each rule file name follows the naming convention: Org.Resource.Policy.Rule.yaml.

Example custom rule to enforce mandatory tags:

# File: ps-rule/Org.Resource.Tagging.Rule.yaml
type: Rule
name: Org.Resource.Tagging
description: |
  Ensure all resources have required tags.
condition:
  anyOf:
    - field: tags.Environment
      equal: "Production"
outcome: "Fail"

Step 2: Update ps-rule.yaml Configuration

In the root ps-rule.yaml configuration file, enable Bicep file expansion and configure type binding to allow PSRule to interpret and validate Bicep modules fully.

configuration:
  AZURE_BICEP_FILE_EXPANSION: true
binding:
  targetType:
    - "resourceType"

Step 3: Integrate Custom Rules into the Azure DevOps Pipeline

  1. Update the Pipeline YAML File: Add a job to execute PSRule against custom rules, referencing the ps-rule directory and custom configuration file.
- task: bewhite.ps-rule.assert.ps-rule-assert@2
  inputs:
    source: "$(System.DefaultWorkingDirectory)/Modules"
    configuration: "$(System.DefaultWorkingDirectory)/ps-rule/ps-rule.yaml"
    modules: PSRule.Rules.Azure
    outputFormat: Sarif
    outputPath: "$(Pipeline.Workspace)/a/CodeAnalysisLogs/ps-rule-results.sarif"
    include:
      module: 
        - PSRule.Rules.Azure
        - "$(System.DefaultWorkingDirectory)/ps-rule/*.Rule.yaml"  # Custom rules
    continueOnError: true
  1. Run Pipeline and Review Results: This pipeline job will validate your Bicep modules against both Azure’s best practices and custom compliance rules defined in your custom PSRule files.

Example Use Cases for Custom Rules

  1. Mandatory Tags Check: Ensuring required tags are present on each resource.
  2. Restricted Resource Configuration: Limiting certain settings, such as SKU or location, to meet organizational guidelines.
  3. Azure Policy Simulation: Checking against specific rules your organization enforces with Azure Policy, allowing you to validate compliance before deployment.

Final Thoughts

Integrating custom PSRule checks into your Azure DevOps pipeline adds a crucial layer of proactive compliance validation, ensuring Bicep modules meet both Azure best practices and custom organizational standards.

For more details on setting up PSRule and Bicep modules, check out my original article on creating and testing Bicep modules and follow-up on enhancing testing with PSRule.

Together, these resources help establish a comprehensive, policy-compliant approach to IaC validation.

Have experience with custom PSRule rules? Share your thoughts below!