Terraform action changed after modify the resource modules

Hi there,

I am using Terrafrom for about 4 years and recently, I plan to uppgrade Terraform from v0.12.29 to v0.14.8. So, I am trying of v0.14 new deployment.

The big difference of v0.14 is that the plugin/Provider need to be specified explicitly.
I use local providers as there is no network to public.

$ ls terraform.d/plugins/terraform.io/hashicorp/openstack/1.40.0/linux_amd64/
terraform-provider-openstack_v1.40.0

File provider.tf:

terraform {
  required_version = ">= 0.13"
  required_providers {
    openstack = {
      version = "1.40.0"
      source  = "terraform.io/hashicorp/openstack"
    }
  }
}
provider "openstack" {
}

First of all, let me explain how I use terraform modules.

  1. I separate all resources into modules, one moduel contain one template named main.tf, such as
$ ls modules/  -1r
server_group_v2
security_groups
networks
keypair_v2
instance
glance_images
  1. In openstack.tf file, I would define several modules per resouces type and nodes.
$ cat openstack.tf | grep modules/ -C1
module "master-01" {
    source = "./modules/instance/pkq-01/group_01/"
    ssh_user    = "cloud-user"
module "slaver-01" {
    source = "./modules/instance/pkq-01/group_02/"
    ssh_user    = "cloud-user"
module "slaver-02" {
    source = "./modules/instance/pkq-01/group_02/"
    ssh_user    = "cloud-user"
module "keypair_1" {
    source = "./modules/keypair_v2/pkq-01"
}

After following several guides, now the resource creation works after adding above provider.tf in each templates.
However, my issue happened when I want to do some lifecycle event, such as scale-in one node.

In v0.12, I just need remove the module “slaver-02” block within file openstack.tf and the run terraform apply, the according node will be deleted, then tfstate file will also be updated. In other words, my openstack.tf is always up-to-date.

But in v0.14, using same way to comment/delete the module block in openstack.tf, error was reported by terraform plan/apply:

// module "slaver-02" {
//     source = "./modules/instance/pkq-01/group_02/"
//     ssh_user    = "cloud-user"

(just one sub-resources as example)

$ terraform  plan -state=terraform.tfstate.pkq-01
Error: Provider configuration not present

To work with
module.slaver-02.openstack_networking_port_v2.port_net-02_v4 (orphan)
its original provider configuration at
module.slaver-02.provider["terraform.io/hashicorp/openstack"] is
required, but it has been removed. This occurs when a provider configuration
is removed while objects created by that provider still exist in the state.
Re-add the provider configuration to destroy
module.slaver-02.openstack_networking_port_v2.port_net-02_v4
(orphan), after which you can remove the provider configuration again.

I am not sure whether it is as expected as terraform v0.14 enhanced the terraform plan/apply method. (or my usage is not correct ? but v0.12 works well)

My Questions:

  1. Not sure if there is a more efficient way of adding provider.tf to each module template folder ?
    As I use the only one local openstack provider, is one global provider definition supported or not for v0.14 ?

  2. Regading above “Provider configuration not present” error, any idea or hint for me ?
    I know the cmd of “terraform destroy -target module.slaver-02” and then update openstack.tf file works, but I still want to find a way to be compatible with the method in v0.12.

  3. I know in deveploment level, v0.12 is not suggested to use or without any fix/new features. But I still could use v0.12, right ?
    Without TLS 1.3 or Unicode 12.0 character tables, etc. Any other potential issues of keep using v0.12 ?

Hi @pkqsun,

It appears that your configuration is missing the providers meta argument in the module blocks. The module contains an empty configuration for the openstack provider, which means it’s expecting a configuration to be passed in from the parent module. See Providers Within Modules - Configuration Language - Terraform by HashiCorp

If you want to automatically inherit the provider from the parent module, you need to remove the empty configuration block.

You can also try this out with the 0.15 prerelease, which has significantly more validation in place to guide you through properly configuration providers in modules.

Hi @jbardin ,

Thanks a lot for your reply.
After remove the empty provider block in provider.tf file, now the action of scale-in is back to normal as before. :+1:

After v0.15 are official released, I would try it. :grinning:

Have a nice day !

Hi @jbardin ,

One more question:

When my provider block is not empty, how should I specify the providers in modules?
Refer to above guide, I am still confused with how to do that without alias.

  //  In root module of vsphere.tf
    terraform {
      required_version = ">= 0.13"
      required_providers {
        vsphere = {
          version = "1.25.0"
          source  = "terraform.io/hashicorp/vsphere"
        }
      }
    }

provider "vsphere" {
  user = "user1"
  password = "passwd1"
  vsphere_server = "IP1"
  allow_unverified_ssl = "true"
}

//

module "master-01" {
    source = "./modules/instance/pkq-01/group_01/"
    hostname  = "master-01"
    datacenter    = "Datacenter1"
    cluster = "Cluster1"
    datastore  = "vsanDatastore"


    volume_size = "100" 

    providers = {
      // All are incorrect as terraform still finding latest version of hashicorp/vsphere...
       vsphere = vsphere    //  this line works after add below comments
     // vsphere = master-01
     // vsphere = vsphere_virtual_machine
     // vsphere = ??

       }
}

update:

Refer to Include Providers from child modules in the root module?, after add another terraform block of

terraform {
    required_version = “>= 0.13”
    required_providers {
    vsphere = {
        version = “1.25.0”
        source = “terraform.io/hashicorp/vsphere”
       }
   }
}

in source folder/ child modules, the init and apply works.