Terraform v0.13.0
+ provider registry.terraform.io/hashicorp/consul v2.9.0
+ provider registry.terraform.io/hashicorp/helm v1.2.4
+ provider registry.terraform.io/hashicorp/kubernetes v1.12.0
+ provider registry.terraform.io/hashicorp/local v1.4.0
+ provider registry.terraform.io/hashicorp/null v2.1.2
+ provider registry.terraform.io/hashicorp/template v2.1.2
+ provider registry.terraform.io/hashicorp/vault v2.12.2
+ provider registry.terraform.io/hashicorp/vsphere v1.22.0
+ provider registry.terraform.io/rancher/rancher2 v1.10.0
+ provider registry.terraform.io/rancher/rke v1.0.1
main.tf:
module "vm_config" {
source = "https://gitlab-web.#######/terraform/terraform-###-vm-config/-/archive/1.0.0/terraform-###-vm-config-1.0.0.tar.gz"
stage = var.cm_stage
application = var.cm_application
tier = "data_tier"
}
terraform-###-vm-config/main.tf
main.tf:
module "ip_allocation" {
source = "https://gitlab-web..#######/terraform/terraform-###-ip_allocation/-/archive/1.0.0/terraform-###-ip_allocation-1.0.0.tar.gz"
stage = var.stage
application = var.application
tier = var.tier
}
Error: Unsupported argument
on cm_data.tf line 6, in module "vm_config":
6: stage = var.cm_stage
An argument named "stage" is not expected here.
Terraform Init should also parse the Child Modules for module block and resolve the specified source
Terraform resolve only module blocks in the root module
terraform initI try to abstract the retrieval of our configuration data for the deployment of virtual machines on vsphere.
I wrote a module that collects data like, ip adress, vlan, datastore and so on from various sub modules. Those Sub Module fetched the configuration from various data sources or generate the ressource like ip address from the infoblox appliance.
That way i can use the vm_config module in my root and get a full config for my vm to use. The modules are working without problem when using local path. But when i upload the modules to our gitlab only the first level of child modules is loaded. the module blocks within the vm-config module ar not resolved. When i then run terraform plan i get an error because the modules vm-config needed are note available.
I did a few additional tests. When i use a local source for the vm_config module the child module inside vm_config are loaded via https.
Changed
source = "https://gitlab-web.#######/terraform/terraform-###-vm-config/-/archive/1.0.0/terraform-###-vm-config-1.0.0.tar.gz"
to
source = "../modules/terraform-xyz-vm-config/"
And i got
terraform init
Initializing modules...
- vm_config in ../modules/terraform-###-vm-config
Downloading https://gitlab-web.#####/terraform/terraform-###-datastore/-/archive/1.0.0/terraform-###-datastore-1.0.0.tar.gz for vm_config.datastore...
- vm_config.datastore in .terraform/modules/vm_config.datastore
Downloading https://gitlab-web.#####/terraform/terraform-###-ip_allocation/-/archive/1.0.0/terraform-###-ip_allocation-1.0.0.tar.gz for vm_config.ip_allocation...
- vm_config.ip_allocation in .terraform/modules/vm_config.ip_allocation
Downloading https://gitlab-web.#####/terraform/terraform-###-ip_network/-/archive/1.0.0/terraform-###-ip_network-1.0.0.tar.gz for vm_config.ip_network...
- vm_config.ip_network in .terraform/modules/vm_config.ip_network
Downloading https://gitlab-web.#####/terraform/terraform-###-network/-/archive/1.0.0/terraform-###-network-1.0.0.tar.gz for vm_config.network...
- vm_config.network in .terraform/modules/vm_config.network
- vsphere_data in ../modules/terraform-###-vsphere_data
Hi @PSTobiasMueller !
While this should work, I want to start by noting that the module documentation explains that the best practice is for any nested module source to be a relative, local path, instead of another module.
I wasn't able to reproduce this issue using an (admittedly silly) reproduction case which pointed to a module's example directory to force it to download the module twice:
module "module-installer-acctest" {
source = "hashicorp/module-installer-acctest/aws//examples/main"
version = "0.0.2"
}
Here I can see that the module is downloaded twice, once from the "source" configured in my root module and once from the "source" in the nested module:
Initializing modules...
Downloading hashicorp/module-installer-acctest/aws 0.0.2 for module-installer-acctest...
- module-installer-acctest in .terraform/modules/module-installer-acctest/terraform-aws-module-installer-acctest-0.0.2/examples/main
Downloading hashicorp/module-installer-acctest/aws 0.0.2 for module-installer-acctest.root...
- module-installer-acctest.root in .terraform/modules/module-installer-acctest.root/terraform-aws-module-installer-acctest-0.0.2
- module-installer-acctest.root.child_a in .terraform/modules/module-installer-acctest.root/terraform-aws-module-installer-acctest-0.0.2/modules/child_a
- module-installer-acctest.root.child_a.child_b in .terraform/modules/module-installer-acctest.root/terraform-aws-module-installer-acctest-0.0.2/modules/child_b
We will need you to provide a reproduction case which we can run locally to reproduce the issue you are seeing.
Hi @mildwonkey,
i attached some example modules for you to test.
ExampleModules.zip
The Child Modules are
The terraform-xyz-vm-config is sort of a "controller" module and test-nested-module is the root module that would later deploy the vm.
What we tried to accomplish with this nested modules was, that each team could maintain there own module. For example the IPAM Team would maintain the terraform-xyz-ip_allocation and the Datastore Team would maintain terraform-xyz-datastore.
The only requirement to the ip_allocation module for example is the return value of a new ip. How that ip is obtained is totally in response of the IPAM Team. Currently they use an Infoblox for IP Allocation but maybe they switch to antoher sytem in a year, then the only module we have to change is the ip_allocation module. But not all other scripts that may need an IP for a vm, a citrix load balancer or a kubernetes load balancer.
if you have better ideas how to accomplish this scenario i'm happy to hear from you.
Thank you for the examples, but I need something that I can actually run locally and see the issue that you've reported (not all modules getting installed) - is it possible for you to create a public repository with these modules so we can run terraform init on the main.tf in test-nested-module?
module "vm-config" {
source = "https://gitlab-web.###.net/terraform/terraform-xyz-vm-config/-/archive/1.0.0/terraform-xyz-vm-config-1.0.0.zip"
stage = "test"
application = "kasse"
tier = "data_tier"
}
~Having said that, ~
(Sorry, hit post mid thought!) This certainly _looks_ like a configuration that should init properly and, and your module development strategy is a very common (and good) pattern. Unfortunately we'll need more information - a reproduction will be best, though it would also help if you could post up the TRACE level logging of terraform init too (as a gist, please, and remove any sensitive data!)
Thnaks!. I'll "rebuild" the example on github. And will post the logs from an init proccess tomorrow.
Hello @mildwonkey,
thanks to you, i found the problem and a solution. Terraform seems to handle/parse modules differently that are provided as URL source in tar.gz or zip.
I've uploaded a nested Module example on Github. When i use the code below it is working. When i change the source to the same module, but as tar.gz download. Then it will only download the examplevm-config module.
module "vm_config" {
# Working Source
source = "github.com/PSTobiasMueller/terraform-example-vm-config"
# Not Working Source
# source = "https://github.com/PSTobiasMueller/terraform-example-vm-config/archive/v1.0.tar.gz"
stage = var.stage
application = var.application
tier = var.tier
}
I've also found a solution for use with gitlab. I can use the git:: source:
source = git::https://gitlab-web.#####/terraform/terraform-xyz-vm-config.git
I don't know if you would consider the handling of the http-urls as a bug that should be resolved. If not it would be good to add
at the module source doku that nesting modules are not supported in this case.
Great, thanks for sharing the reproduction case! I'm glad you have a workaround. This looks like it might be expected behavior on the part of the go-getter library that handles the downloads unpacks the archive into a directory.
TL;DR in case you don't want to read the wall of text below:
Changing the source to include a subdirectory that matches the name of the archive directory fixed the problem:
source = "https://github.com/PSTobiasMueller/terraform-example-vm-config/archive/v1.0.tar.gz//terraform-example-vm-config-1.0"
This is interesting, and how I figured out what was going on. Here's what my .terraform/modules directory looks like after the first ("bad") init - note the subdirectory terraform-example-vm-config-1.0 under vm_config:
.terraform/modules/
โโโ modules.json
โโโ vm_config
โย ย โโโ terraform-example-vm-config-1.0
โย ย โโโ README.md
โย ย โโโ data.tf
โย ย โโโ main.tf
โย ย โโโ outputs.tf
โย ย โโโ provider.tf
โย ย โโโ variables.tf
โย ย โโโ variables.tfvars
And here's what it looks like in the working version (omitted the other modules - but they are all there):
[kristin@fairy /tmp/scratch] tree .terraform/modules/
.terraform/modules/
โโโ modules.json
โโโ vm_config
โย ย โโโ README.md
โย ย โโโ data.tf
โย ย โโโ main.tf
โย ย โโโ outputs.tf
โย ย โโโ provider.tf
โย ย โโโ variables.tf
โย ย โโโ variables.tfvars
This makes sense now that I have this information; when you unzip an archive of a directory you get the directory, too, and not just the files. With that information, I updated your module source to the following (adding a sub-directory at the end, which tells terraform to look in that dir for the module), and it downloaded all the nested modules as expected:
source = "https://github.com/PSTobiasMueller/terraform-example-vm-config/archive/v1.0.tar.gz//terraform-example-vm-config-1.0"
If the tarball contained just files, you wouldn't have encountered this issue.
I am going to label this as a documentation issue so we can add a note about this behavior (specific to using an archived directory) on that module installation page you linked.
I'm going to lock this issue because it has been closed for _30 days_ โณ. This helps our maintainers find and focus on the active issues.
If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.