Open ctreatma opened 6 months ago
At the heart of this is the benefit, or perceived benefit, of Terraform modules. Who is the audience of the module, how will they use it? Who will build and maintain the module? How and where will it be reused?
Deferring to Hashicorp to guide and form module definition to suite the multitude of options and paths, I took another look at what a module is and how it should be presented according to the TF docs.
Hashicorp has recommendations and suggestions that include:
IMHO, this lends itself towards:
I recognize that my understanding of module best-practices has shifted after this round of reviewing Hashicorp documentation, specifically around the importance of root modules and their need for provider config.
For newer modules like terraform-equinix-fabric and terraform-equinix-network-edge we do not currently have a root module.
The Hashicorp recommendations, requirements, suggest these should have a root module, but what would it represent? If these were to be presented like terraform-equinix-labs, then Fabric and NE would expose gates to access all of the child-modules. I haven't found direct guidance to support this, but I believe this does not conflict with the thin-wrapper advice. The modules would have a conditional one-to-one relationship rather than a basic one-to-one relationship with their resources.
Does this mean the root module of equinix-labs has a giant provider block to emcompass all the possible providers used by the modules/ ?
While best practices are important and good to be aware of, there is a reason they aren't required practices: depending on the situation, best practices may accomplish the opposite of what is desired. The question in this issue is not what HashiCorp recommends for module structure. Those recommendations are generally influenced by the experience of using terraform modules in production. Those recommendations may apply to the Network Edge and Fabric modules, but our modules are explicitly not meant for production (and I think we even have disclaimers in a couple places that they don't reflect best practices).
The questions this issue raises are:
My understanding is that (1) is settled: our modules are intended for education and reference.
Assuming the above is true, I contend that the answer to (2) is that our modules benefit from having the configuration in the root so that it is easy to see what we're doing. It is an exercise left to the reader to restructure the configuration for production use cases; if users pull in chunks of our config without thinking about it carefully, we have failed to educate them and have accidentally released a production thing.
It seems that the answer to (3) is that Labs aims to make it easier to run workshops that focus on a specific module, either EKS-A, or Nutanix, or Anthos, or something else. Currently Labs does that by being a big umbrella repo that forces our modules to support the count
meta-argument, which means introducing indirection in our modules that makes them harder to use for reference.
Given the above, one alternative could be that a "lab" is an example that gets added to each module, rather than an umbrella that covers all modules. That keeps the lab config closer (physically/organizationally) to the underlying module and removes the need for our modules to support the count
meta-argument so that we continue to make things readily visible for individual users referring to our modules, which is currently the most common use case for our modules.
What is the actual likelihood of an organization exclusively for this purpose, like https://github.com/terraform-aws-modules
I think we should reconsider having the terraform-equinix-labs repo, or at least reiterate the goals it aims to achieve and consider if there are alternatives that would better fit the experimental/educational aspect of equinix-labs repos. IMO a benefit of equinix-labs modules is the ability to easily see the code and use it as a reference. If I come to a module through the Labs repo, I have to dig through a couple layers of indirection before I finally figure out where to look for the actual code I'm interested in. This could be improved slightly by using GitHub sources for modules instead of Terraform registry sources (e.g., source = "github.com/equinix-labs/terraform-equinix-metal-eks-anywhere" instead of source = "equinix-labs/metal-eks-anywhere/equinix"), but I still have to go from Labs example => Labs main module => Labs submodule just to find that source attribution.
In addition, using this repo as a landing place for our modules forces us to implement those modules in a way that is perhaps undesirable. This repo uses
count
to dynamically select which modules are enabled for a given run ofterraform plan/apply
. Modules cannot be used withcount
if they include explicit provider configuration, but our template repo creates modules with explicit provider configuration. This makes it easier to develop and try out the modules that are created from the template: just set up your var file and go. If we change the template and/or our modules to remove explicit configuration, then we have to useexamples
to run the module, which again adds indirection when someone is trying to understand what the code does and why.