Terraform Test with TFC workspaces

Hi all

Today I am trying to play with Terraform Test in Terraform Cloud (TFC).

My objective is to:

  1. Specify the TFC workspace to use in the Terraform Test “module” block.
  2. Attach RunTasks to the TFC workspace
  3. Triggers RunTasks as part of post-plan

I managed to get Terraform Test to initialize the TFC workspace, attach the RunTask, and do some checks such as RunTask id, etc.

However I cant get it to trigger the RunTasks to run as part of the post-plan.

Does Terraform Test support RunTasks as part of the workflow?

Hi @wellsiau,

The Terraform Cloud implementation of module testing is designed as something entirely separate from workspaces, that happens in the private module registry so that the testing can happen before a new version of the module has been published, rather than in a sense testing it “in production” inside a workspace that depends on it.

However, you’ve mentioned Run Tasks in the question which makes me think I don’t fully understand what you’ve set up. Are you trying to use Run Tasks to run terraform test directly? Or something else?

Thanks!

@apparentlymart , thanks for your reply. I am familiar with the TFC module testing in the private registry (pretty neat!). However in my case, I didn’t publish my module to the registry to trigger such workflow.

In my use-case, I wrote a Terraform test scenario as follow:

Run 1 (setup)

  1. Deploy a RunTask on TFC org

Run 2 (attach)

  1. Create a test workspace in TFC
  2. Attach the RunTask to the test workspace in TFC

Run 3 (validate)

  1. Deploy a module against the test workspace
  2. Trigger terraform plan (command = plan)

I was able to complete Run 1 and 2 successfully and confirmed that the RunTask indeed was created on the TFC org.

Run 3 also runs successfully on-paper, however I can confirm whether the test workspace did actually trigger RunTask to run (which if it does, it should actually fail Run 2 due to RunTask enforcement level).

For example, given a “setup” module that look like this:

terraform {
  cloud {
    organization = "wellsiau-org"
    workspaces {
      name = "aws-ia2-Module-Workspace"
    }
  }
  . . .
module "runtask_iam_access_analyzer" {
  source           = "../../" 
  tfc_org          = var.tfc_org
  aws_region       = data.aws_region.current.name
  workspace_prefix = var.workspace_prefix
}

And the “attach” module as follow:

terraform {
  cloud {
    organization = "wellsiau-org"
    workspaces {
      name = "aws-ia2-Demo-Workspace"
    }
  }

. . .
}

# attach the runtask to a test workspace
resource "tfe_workspace_run_task" "aws-iam-analyzer-attach" {
  count             = var.flag_attach_runtask ? 1 : 0
  workspace_id      = data.tfe_workspace.workspace.id
  task_id           = var.runtask_id
  enforcement_level = var.runtask_enforcement_level
  stage             = var.runtask_stage
}

then my test scenario are as follow:

run "runtasks_is_setup" {
  # run this first to deploy the setup module (which creates the RunTask)
  module {
    source = "./tests/setup"
  }

  assert {
    # runtask id always start with task-xxxx
    condition = substr(module.runtask_iam_access_analyzer.runtask_id, 0, 4) == "task"
    error_message = "Invalid run tasks id / failed to create run tasks"
  }
}

run "attach_workspace" {
  # create new test workspace and attach run task to test workspace
  variables {
    flag_attach_runtask = "true"
    runtask_enforcement_level = "mandatory"
    runtask_stage = "post_plan"
    runtask_id = run.runtasks_is_setup.runtask_id
  }

  module {
    source = "./tests/attach"
  }

  assert {
    # Workspace runtask id always start with wstask-xxxx
    condition = substr(tfe_workspace_run_task.aws-iam-analyzer-attach[0].id, 0, 6) == "wstask"
    error_message = "Invalid workspace run tasks id / failed to attach run tasks to workspace"
  }
}

run "validate_access_analyzer" {
  # run terraform plan on the test workspace to trigger RunTask to run and provide results
  command = plan 
  
  variables {
    flag_attach_runtask = "true"
    flag_deploy_invalid_resource = "true"
    runtask_enforcement_level = "mandatory"
    runtask_stage = "post_plan"
    runtask_id = run.runtasks_is_setup.runtask_id
  }

  module {
    source = "./tests/attach"
  }
  
  # some assertions here , need to write it 
}

In my case, I can’t prove / validate that the run “validate_access_analyzer” are actually executed inside the TFC workspace as opposed to somewhere “local” within the Terraform Test itself.

Hi @wellsiau,

Thanks for the additional information. I had totally misunderstood what you were doing, so I’m sorry about that. I see now that what you intend to do is write a test for a module that happens to be using the hashicorp/tfe provider to configure Run Tasks for a workspace.

Unfortunately I don’t think I know enough about Terraform Cloud Run Tasks to offer more advice here; my focus is typically on Terraform Core, so I’m not an expert on all Terraform Cloud features. Hopefully someone else will be able to help with this question.

1 Like

@apparentlymart , no worries and thank you for taking a look at it.

This is certainly edge cases, I picked one of our most complex module to test-drive Terraform Test. Hopefully someone else could chime in later.