Using multiple mocks

Greetings,

I am trying to use multiple mocks in my sentinel test but I can’t get the mocks I added to be used.

Folder setup
enforce-route-table-on-subnet.sentinel
enforce-route-table-on-subnet
  mockdata
    mock-modules-tfconfig-fail.sentinel (doesn’t get used)
    mock-modules-tfconfig-pass.sentinel (doesn’t get used)
    mock-modules-tfplan-pass.sentinel (doesn’t get used)
    mock-modules-tfplan-fail.sentinel (doesn’t get used)
    mock-tfconfig-fail.sentinel (gets used)
    mock-tfconfig-pass.sentinel (gets used)
    mock-tfplan-fail.sentinel (gets used)
    mock-tfplan-pass.sentinel (gets used)
  fail.json

{
    "modules": {
        "tfplan-functions": {
            "path": "../../tfplan-functions.sentinel"
        },
        "tfconfig-functions": {
            "path": "../../tfconfig-functions.sentinel"
        }
    },
    "mock": {
        "tfplan/v2": "./mockdata/mock-tfplan-fail.sentinel",
        "tfconfig/v2": "./mockdata/mock-tfconfig-fail.sentinel",
        "tfplan-modules/v2": "./mockdata/mock-modules-tfplan-fail.sentinel",
        "tfconfig-modules/v2": "./mockdata/mock-modules-tfconfig-fail.sentinel"
	},
	"test": {
		"main": false
	}
}

  pass.json

{
	"modules": {
        "tfplan-functions": {
            "path": "../../tfplan-functions.sentinel"
        },
        "tfconfig-functions": {
            "path": "../../tfconfig-functions.sentinel"
        }
    },
    "mock": {
        "tfplan/v2": "./mockdata/mock-tfplan-pass.sentinel",
        "tfconfig/v2": "./mockdata/mock-tfconfig-pass.sentinel",
        "tfplan-modules/v2": "./mockdata/mock-modules-tfplan-pass.sentinel",
        "tfconfig-modules/v2": "./mockdata/mock-modules-tfconfig-pass.sentinel"
	},
	"test": {
		"main": true
	}
}
$ sentinel test -verbose -run=enforce-route
PASS - enforce-route-table-on-subnet.sentinel
  PASS - test/enforce-route-table-on-subnet/fail.json


    logs:
      azurerm_subnet.subnet1 does not have an associated route table
      azurerm_subnet.subnet2 does not have an associated route table
    trace:
      FALSE - enforce-route-table-on-subnet.sentinel:78:1 - Rule "main"
  PASS - test/enforce-route-table-on-subnet/pass.json


    logs:
      azurerm_subnet.subnet1
      module.hub_virtual_network.azurerm_subnet.subnet2
      azurerm_subnet.subnet1
      module.hub_virtual_network.azurerm_subnet.subnet2
    trace:
      TRUE - enforce-route-table-on-subnet.sentinel:78:1 - Rule "main"

Hi again, @wblanchard-concurren,

So, I see two problems in the files you shared.

  1. Test cases used with the sentinel test command need to be under a directory with the same name as the policy without the .sentinel extension under a test directory that sits where the policy sits. Your tree above shows what appears to be a “enforce-route-table-on-subnet” directory at the same level as the corresponding policy instead of under a test directory at that level. Perhaps, this was just an oversight in your description of the tree?
  2. You cannot refer to made-up mock types such as “tfplan-modules/v2”. If you have actually defined your own Sentinel modules called “tfplan-modules” and “tfconfig-modules”, then you should reference them with modules, not with mocks.

Additionally, any test case should have at most one reference to any mock including mocks of type “tfplan/v2”, “tfconfig/v2”, “tfstate/v2”, and “tfrun”. Mocks are intended to give mocked data for a specific import. At runtime in Terraform Cloud or Terraform Enterprise, the actual data made available to Sentinel for any Sentinel import would only consist of a single set of data. So, using two mocks of the same type in Sentinel CLI test cases just does not make sense.

If you share your the contents of your policy and your tfplan-modules/v2 and tfconfig-modules/v2 mocks and explain what the purpose of the latter mocks are, perhaps I can assist further.

Roger Berlind
Global Technology Specialist

Hey @rberlind,

I was able to get the answer to the question via support. Thanks for your quick response. I had to create an additional pass.hcl/fail.hcl for the modules.

enforce-route-table-on-subnet
|
|- pass.hcl
|- fail.hcl
|- pass-modules.hcl
|- fail-modules.hcl

So, I think what you wanted to do was use more than 2 test cases. That makes sense. Each test case would then have its own mocks.

You might find my Sentinel for Terraform workshop usedul. See https://storage.googleapis.com/instruqt-hashicorp-tracks/sentinel-shared/Sentinel-for-Terraform-v4.pptx.

Roger Berlind

1 Like