Acceptance Testing using a local External Provider

Hi,

I am currently trying to migrate a private Terraform Provider from the legacy SDK V2 over to the Plugin Framework. I’m happy that the plan generated using the new resource provider is a no-op when switching from the legacy SDK provider to the framework provider as I have tested this manually. However I am trying to write an acceptance test as per the guide here and have hit a problem:

As this is a private provider I need the ExternalProviders to be picked up from a local directory rather than trying to download it from a registry and I am struggling to get this working.

Setup is as follows:

SDK provider name → terraform-provider-mysdk-provider
Framework provider name → terraform-provider-myframework-provider

Test setup is as follows:

func TestAccGroupMigrationTest(t *testing.T) {
	resource.Test(t, resource.TestCase{
		Steps: []resource.TestStep{
			{
				ExternalProviders: map[string]resource.ExternalProvider{
					"sdkprovider": {
						VersionConstraint: "<=1.0.85",
						Source:            "mycompany/sdkprovider",
					},
				},
				Config: `data "provider_datasource" "example" {
                         /* ... */
                     }`,
				Check: resource.ComposeTestCheckFunc(
					resource.TestCheckResourceAttr("data.provider_datasource.example", "<attribute>", "<value>"),
					/* ... */
				),
			},
			{
				ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
				Config: `data "provider_datasource" "example" {
                         /* ... */
                     }`,
				PlanOnly: true,
			},
		},
	})
}

I am trying to get it so that when the acceptance test runs it will look in my local plugins directory for the old version of the provider i.e. terraform-provider-mysdk-provider but I can’t work out how to do this properly. I don’t think dev_overrides comes into play for an acceptance test do they although I might be wrong on this?

I’ve tried dropping the binary of the provider into ~/.terraform.d/plugins with the appropriate directory structure but it doesn’t seem to get picked up and enabling trace logging shows no attempt to load from the plugins directory.

Any help or examples for doing this would be greatly appreciated. Thanks!

Paul

Hi,

I’ve solved this now with the following setup.

I am on a Mac M2 so the architecture is darwin_arm64.

I’ve built my provider and placed it in

/$HOME/.terraform.d/plugins/registry.terraform.io/org/myprovider/<version>/darwin_arm64
Then my .terraformrc file (in $HOME) looks like this:

plugin_cache_dir = "$HOME/.terraform.d/plugin-cache"
provider_installation {
  filesystem_mirror {
    path = "$HOME/.terraform.d/plugins"
  }
  direct {
    exclude = ["org/*/*"]
  }
}

NOTE that in the .terraformrc file, for the path $HOME needs to be expanded to the real value rather than using the environment variable

Then my migration test defines this for the external provider:

resource.Test(test, resource.TestCase{
		Steps: []resource.TestStep{
			{
				ExternalProviders: map[string]resource.ExternalProvider{
					"myprovider": {
						VersionConstraint: "<version>",
						Source:            "org/myprovider",
					},
				},

This now works, picks up the external provider and runs the test correctly.

Hope this helps!

Paul

I think there is simpler, here is my local .terraformrc file (also on mac M2 btw)


provider_installation {

dev_overrides {

"registry.terraform.io/providers/my-provider" = "<MY-GOBIN-PATH>"

}

direct {}

}

and I just go install