Skip to content

Writing Tests⚓︎

Consult OPA's documentation for general information on writing test rules, whose names must begin with test_ (e.g., test_my_rule).

Test inputs start with an IaC file. Regula dynamically generates various kinds of test inputs from a single IaC file.

The test input used for simple and advanced rules is different:

For a deep dive into test input, see Test Inputs.

Writing a test for a simple rule⚓︎

Suppose you're writing a simple rule that checks whether AWS EBS volumes are encrypted:

package rules.tf_aws_ebs_volume_encrypted_simple

resource_type = "aws_ebs_volume"

default allow = false

allow {
  input.encrypted == true
}

Here's the test IaC you might use as test input, containing a valid (encrypted) and invalid (unencrypted) EBS volume, and the mock_resources Regula generates from it:

provider "aws" {
  region = "us-east-2"
}

resource "aws_ebs_volume" "good" {
  availability_zone = "us-west-2a"
  size              = 40
  encrypted         = true
}

resource "aws_ebs_volume" "bad" {
  availability_zone = "us-west-2a"
  size              = 40
  encrypted         = false
}
{
  "aws_ebs_volume.bad": {
    "_provider": "aws",
    "_type": "aws_ebs_volume",
    "availability_zone": "us-west-2a",
    "encrypted": false,
    "id": "aws_ebs_volume.bad",
    "size": 40
  },
  "aws_ebs_volume.good": {
    "_provider": "aws",
    "_type": "aws_ebs_volume",
    "availability_zone": "us-west-2a",
    "encrypted": true,
    "id": "aws_ebs_volume.good",
    "size": 40
  }
}

Finally, here is the test file for the simple rule. It contains two tests, a valid and invalid case. Note that because this is a simple rule, mock_resources is imported as test input (see this note about the package name):

package rules.tf_aws_ebs_volume_encrypted_simple

import data.volume_encrypted_infra_tf.mock_resources

test_valid_ebs_volume_encrypted {
  allow with input as mock_resources["aws_ebs_volume.good"]
}

test_invalid_ebs_volume_encrypted {
  not allow with input as mock_resources["aws_ebs_volume.bad"]
}

Writing a test for an advanced rule⚓︎

Suppose you've written an advanced rule that checks whether AWS EBS volumes are encrypted. For this example, we've just converted the simple rule above to an advanced rule:

package rules.tf_aws_ebs_volume_encrypted_advanced

import data.fugue

resource_type = "MULTIPLE"

volumes = fugue.resources("aws_ebs_volume")

policy[p] {
  volume = volumes[_]
  volume.encrypted == true
  p = fugue.allow_resource(volume)
} {
  volume = volumes[_]
  volume.encrypted == false
  p = fugue.deny_resource(volume)
}

You can use the same test IaC for test input, but this time, you'd use the mock_input:

provider "aws" {
  region = "us-east-2"
}

resource "aws_ebs_volume" "good" {
  availability_zone = "us-west-2a"
  size              = 40
  encrypted         = true
}

resource "aws_ebs_volume" "bad" {
  availability_zone = "us-west-2a"
  size              = 40
  encrypted         = false
}
{
  "resources": {
    "aws_ebs_volume.bad": {
      "_provider": "aws",
      "_type": "aws_ebs_volume",
      "availability_zone": "us-west-2a",
      "encrypted": false,
      "id": "aws_ebs_volume.bad",
      "size": 40
    },
    "aws_ebs_volume.good": {
      "_provider": "aws",
      "_type": "aws_ebs_volume",
      "availability_zone": "us-west-2a",
      "encrypted": true,
      "id": "aws_ebs_volume.good",
      "size": 40
    }
  }
}

Finally, here is the test file for the advanced rule. It contains one test that checks a valid and invalid case. Because we're testing an advanced rule, mock_input is imported as test input (see this note about the package name):

package rules.tf_aws_ebs_volume_encrypted_advanced

import data.volume_encrypted_infra_tf.mock_input

test_ebs_volume_encrypted {
  pol := policy with input as mock_input
  resources := {p.id: p.valid | p := pol[_]}
  resources["aws_ebs_volume.good"] == true
  resources["aws_ebs_volume.bad"] == false
}

Tip

To learn more about the types of test inputs and how to view them, see Test Inputs.

Example rules and tests⚓︎

You can view the Regula library of rules and accompanying tests for reference. You'll also find some example rules and their tests in the repo.