Skip to content

Using custom rules#

PSRule for Azure covers common use cases that align to the Microsoft Azure Well-Architected Framework (WAF). In addition to WAF alignment you may have a requirement to enforce organization specific rules.

For example:

  • Required tags on a resource group.
  • Code ownership for sensitive resource types.
  • Apply similar controls to Infrastructure as Code that are deployed via Azure Policies.

PSRule allows custom rules to be layered on. These custom rules work side-by-side with PSRule for Azure.

Abstract

This topic covers how you can use custom rules to test Azure Infrastructure as Code (IaC).

Requirements#

For custom rules to work with IaC the following requirements must be configured:

  1. Set a binding configuration.
  2. Configure expansion for processing Bicep or ARM templates.
  3. Include the PSRule.Rules.Azure module.

Set binding configuration#

Rules packaged within PSRule for Azure will automatically detect Azure resources by their type properties. Standalone rules will get their type binding configuration from ps-rule.yaml instead. When binding is not configured, custom rules will typically be ignored.

To configure type binding:

  • Create/ update the ps-rule.yaml file within the root of the repository.
  • Add the following configuration snippet.
ps-rule.yaml
# Configure binding options
binding:
  targetType:
    - 'resourceType'
    - 'type'

Configuring expansion#

PSRule for Azure performs expansion on Bicep and ARM template files it finds in your repository. Enabling expansion is required for testing any IaC in your repository. The requirements for custom rules are no different then using the built-in rules included within PSRule for Azure.

To configure expansion see either:

Including PSRule for Azure#

When creating custom rules to test Azure IaC including PSRule for Azure is required for most scenarios. PSRule for Azure performs expansion on Bicep and ARM template files it finds in your repository.

You can include PSRule for Azure by specifying PSRule.Rules.Azure in one of the following:

Using a standard file path#

Rules can be standalone or packaged within a module. Standalone rules are ideal for a single project such as an Infrastructure as Code (IaC) repository. To reuse rules across multiple projects consider packaging these as a module.

The instructions for packaging rules in a module can be found here:

To store standalone rules we recommend that you:

  • Use .ps-rule/ — Create a sub-directory called .ps-rule in the root of your repository. Use all lower-case in the sub-directory name. Put any custom rules within this sub-directory.
  • Use files ending with .Rule.ps1 | .Rule.yaml | .Rule.jsonc — PSRule uses a file naming convention to discover rules. We recommend using a file name that ends in .Rule.ps1 or .Rule.yaml or .Rule.jsonc.

Note

Build pipelines are often case-sensitive or run on Linux-based systems. Using the casing rule above reduces confusion latter when you configure continuous integration (CI).

Naming rules#

When running PSRule, rule names must be unique. PSRule for Azure uses the name prefix of Azure. on all rules and resources included in the module.

Example

The following names are examples of rules included within PSRule for Azure:

  • Azure.AKS.Version
  • Azure.AKS.AuthorizedIPs
  • Azure.SQL.MinTLS

When naming custom rules we recommend that you:

  • Use a standard prefix — You can use the Local. or Org. prefix for standalone rules.
    • Alternatively choose a short prefix that identifies your organization.
  • Use dotted notation — Use dots to separate rule name.
  • Use a maximum length of 35 characters — The default view of Invoke-PSRule truncates longer names. PSRule supports longer rule names however if Invoke-PSRule is called directly consider using Format-List.

Comments