Provider Configuration in tests

Given a provider that can be configured to point to a different API endpoint:

provider "foo" {
  api_endpoint = "https://staging.foo.com"
}

I would like to run the acceptance tests against a “staging” endpoint. Is there an optimal way to configure this across tests or do I simply have to include a provider configuration block in every configuration that is being tested?

Hi @alkar
The most common way providers are configured in acceptance tests today is by setting appropriate environment variables. That is assuming api_endpoint can be set via ENV variable, which is a good practice in general anyway.

See https://github.com/terraform-providers/terraform-provider-aws/blob/f39af7fff691603f5dc5b553c618d1dbdb6ea0df/aws/provider_test.go#L52-L69 for example.

Alternatively you could pass in the configuration into the Configure call as terraform.ResourceConfig. terraform.NewResourceConfigRaw() can help turning a raw map into the right form.

1 Like

Hi @radeksimko,

Thanks for your reply.

I’ve already tried to use testAccPreCheck as in the aws provider implementation to invoke Configure on the provider, however, that does not seem to persist across the various lifecycle steps of Test: the provider is configured initially (as part of PreCheck) but subsequent steps use an instance of the provider with the default configuration. Doesn’t even work if Configure is called from init() - is this because every step re-initialises the provider?

I also just tried with Setenv and it works as expected, thanks! :+1:

However, I must say it does feel a bit unintuitive having to export environment variables to configure the provider for tests. Wouldn’t it make more sense to include a field in the TestCase struct of type *terraform.ResourceConfig and have the framework use that to configure the provider internally?

That is likely the reason. I would suggest generally leaving Configure for the PreCheck “stage”. This also gives each test the opportunity to change configuration as necessary. e.g. in AWS there are some tests which need to run in a specific region and keeping Configure in PreCheck let us do this.

I may be biased (having worked on Terraform providers where we use this approach for quite a while), but I don’t find it unintuitive. The upside is that you are configuring it the same way users would configure it. The only time I saw this being less convenient is when provider requires some more complex configuration that cannot be represented as a set of strings/integers/bools in ENV variables. Even then though it prompts you to rethink the configuration strategy - which can be positive. If you struggle to configure provider to test it, it’s likely that users will struggle to configure it.

Thanks for the explanation Radek. I’m warming up to the idea myself!

However, what I saw is that even if I call Configure in PreCheck it doesn’t “retain” the configuration. The tests are actually performed with a provider using its default configuration.