Terraform Test Variables

I am building out a VM module and would like to use the new testing framework.
I need alot of information to build the VM in Azure appropriately via the tests:

  • subnet
  • storage (logging location)
  • admin password
    etc.

I have built a “setup_tests” module to gather all the information (data resource lookups) I need and it outputs variables to be used in the subsequent “run” blocks.

Then in the root test.hcl file I build the global variables and reference the run.setup_tests.some_output_var to set a global variable. I am getting the “Variables not allowed” error. Does this mean I can’t use VARS at the GLOBAL level?

variables {
subnet_id = run.setup_tests.subnet_id
}

Error:
│ Error: Variables not allowed

│ on tests\linux_vm.tftest.hcl line 38, in variables:
│ 38: subnet_id = run.setup_tests.subnet_id

│ Variables may not be used here.

When I tried to move the variables into the run block variables I got errors saying:
│ Error: Unsupported attribute

│ on tests\linux_vm.tftest.hcl line 64, in run “valid_linux_os_version_rhel7_l2_plan”:
│ 64: vm_name = “cloudautotest-${run.setup_tests.random_string.random_vm_name.result}”

│ This object does not have an attribute named “random_string”.

So, do all variables have to be hard coded? I thought in this example it appeared that variables from previous modules were allowed? https://github.com/hashicorp-education/learn-terraform-test/blob/24558c98fca526254790bab32f01f0b0979b7601/tests/website.tftest.hcl#L11C7-L11C7

The difference in the example and mine is that the example is in the variables INSIDE the run block vs in the GLOBAL variables. Is that a limitation?

Hi @rockymtnskier,

In your first example you referred to run.setup_tests.subnet_id, but in the second attempt you used run.setup_tests.random_string.random_vm_name.result instead.

Both are potentially valid, but which one is correct depends on how you’ve written the module you are testing. For the first shorter example to work your module must have an output "subnet_id" block whose value is just the subnet id, while for the second you’d need an output "random_string" block whose value is, I suppose, a map of all of your random_string resources.

The first approach seems more typical. If that is what you have then you should be able to use that output value in a later run:

  vm_name = "cloudautotest-${run.setup_tests.subnet_id}"

For any data that you need to pass from one run to another, you will need to declare an output block for it inside the module and then refer to it as I’ve shown above.

Thanks @apparentlymart for help on this one. Yeah that was a typo… the larger issue was that I was not putting those into a “variable” block in the run section. doh! I think we have things working as they should now. Of note, variables can’t be set at the global level that reference output from the run blocks. Order of operations sets the variables and then begins the run blocks execution.