Module design best practice

I am currently trying to agree some standards for writing terraform configuration for my company.

Currently there are a mixture of different structures in use depending on who created the config.

My personal preference is as follows:

  • All manually provided values should be specified in tfvars files only and not in the modules directly. This is to make it easier to check on resource data, easier to re-use modules without having to change values and easier to provide different data for different environments (E.g Lower resource sku for dev)
  • If there is a possibility of needing multiple instances of a resource, the module should be designed to use a for_each to create those from a list instead of having to duplicate the resource block x number of times.
  • Modules should be based around a specific base resource and any related resources that are required. For example, a storage account module would include things such as diagnostic settings, private endpoints and private dns records.

This approach is the cleanest that I have played around with. It is more complex to create the modules but a lot simpler to add new resources. This allows less experienced users to add/update resources without in depth Terraform experience.

My only concerns with this was around ensuring unique and reasonable keys in state files.

As an example, in my network module, the virtual_networks variable is an object list and each virtual network has it’s own object list for it’s subnets. This avoids having to specify a separate list of vnets and subnets in the tfvars files. It does however mean some extra work to ensure that state file keys for the subnets are unique. For this example, i use a combination of the vnet name and subnet name for the key.

I don’t know if there is a limit on state file key name length. I was not able to find anything.

Does anyone have any thoughts on this and can see any potential issues with using lists for everything where appropriate?