equinix-labs / terraform-equinix-labs

Terraform Equinix Labs v0
https://registry.terraform.io/modules/equinix-labs/labs/equinix/latest
Apache License 2.0
3 stars 1 forks source link

Rethink Labs #47

Open ctreatma opened 6 months ago

ctreatma commented 6 months ago

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 of terraform plan/apply. Modules cannot be used with count 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 use examples to run the module, which again adds indirection when someone is trying to understand what the code does and why.

displague commented 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.

cprivitere commented 6 months ago

Does this mean the root module of equinix-labs has a giant provider block to emcompass all the possible providers used by the modules/ ?

ctreatma commented 6 months ago

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:

  1. What is the purpose of our modules? (Reference? Production? Something else?)
  2. How should our modules be structured to best accomplish that purpose?
  3. What does Labs aim to do on top of those modules?
  4. Can we accomplish those aims without forcing potentially undesirable changes to our individual modules?

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.

ocobles commented 6 months ago

What is the actual likelihood of an organization exclusively for this purpose, like https://github.com/terraform-aws-modules