hashicorp / terraform

Terraform enables you to safely and predictably create, change, and improve infrastructure. It is a source-available tool that codifies APIs into declarative configuration files that can be shared amongst team members, treated as code, edited, reviewed, and versioned.
https://www.terraform.io
Other
42.77k stars 9.56k forks source link

Allow mocked values on resources during the planning stage in terraform test #35851

Open buehlmann opened 1 month ago

buehlmann commented 1 month ago

Terraform Version

Terraform v1.9.6 on linux_amd64

Use Cases

I would like to mock calculated attributes on resources in unit tests. By unit tests I mean the command = plan in the run blocks set, because I just want to test conditionals and loops inside my Terraform manifests. In the assert condition of the run block, it should be possible to use the mocked values on the resources.

Attempted Solutions

The resource gitlab_user_runner exposes the computed attribute token, which I use as input for other resources. In my unit test I want to mock the value of this token.

The main Terraform manifest:

# main.tf
provider "gitlab" {
  base_url = "https://gitlab.com/"
}

resource "gitlab_user_runner" "test_runner" {
  runner_type     = "group_type"
  description     = "test-runner"
  group_id        = 42
  tag_list        = ["test-tag"]
}

Testfile where I want to override the token value on gitlab_user_runner.test_runner

# tests/gitlab.tftest.hcl

mock_provider "gitlab" {}

run "test_mock_token" {
  command = plan

  override_resource {
    target = gitlab_user_runner.test_runner
    values = {
      token = "mocked-token"
    }
  }

  assert {
    condition     = gitlab_user_runner.test_runner.token == "mocked-token"
    error_message = "tokens not matching"
  }
}

When executing the test, I get the following error:

│ Error: Unknown condition value
│ 
│   on tests/gitlab.tftest.hcl line 12, in run "test_mock_token":
│   12:     condition     = gitlab_user_runner.test_runner.token == "mocked-token"
│ 
│ Condition expression could not be evaluated at this time. This means you have executed a `run` block with `command = plan` and one of the values your condition depended
│ on is not known until after the plan has been applied. Either remove this value from your condition, or execute an `apply` command from this `run` block.
│

When I run the test with command = plan everything works fine. But in this case I just want to have a unit test, without any resources provisioned.

Proposal

To write proper unit tests it would be a great benefit if one could supply mocked values already during the planning stage.

References

No response

crw commented 1 month ago

Thanks for this feature request! If you are viewing this issue and would like to indicate your interest, please use the 👍 reaction on the issue description to upvote this issue. We also welcome additional use case descriptions. Thanks again!

mud5150 commented 3 weeks ago

Is this an enhancement or a bug? The documentation leads me to believe this should already work.

crw commented 1 day ago

Mind linking the related documentation? I can follow-up from there.