A common complexity with Terraform is deciding when to abstract the code you’re writing into a module, there are many reasons for, and against modules. Further, there is not a Best Practice from HashiCorp around this, not really. One issue that I see often within companies is the overuse of wrapper modules, this is where a resource provided by the Terraform provider is simply wrapped into its own module for consumption by root modules. This can lead to very large and complex dependency chains as each time something is required to be added to this wrapper module a new release must be made, and then respective updates across any of modules consuming this wrapper module.
As such, the below assessment rules have been written to help guide Terraform developers/engineers through the sometimes complex decision of if something should be a module, or it should simply just be consumed by the provider as its base/naked resource.
The following assessment rules utilise RFC-2119 to ensure that the requirements of each rule is easily recognisable.
- If a resource MUST have security/audit/compliance controls enforced at provision and/or configuration time, this MUST then be encapsulated within a Terraform module. Otherwise, it SHOULD be consumed as a Terraform resource.
- When specific configuration or metadata MUST be applied to a resource it MUST then be created as a Terraform module to enforce those requirements.
- When a resource has a stringent/complex naming required that MUST be adhered to these resource MUST be created as a Terraform module.
- When a resource relies on information/metadata/context that cannot be known by the consumer it MUST be created as a Terraform module.
- If a Terraform module will reduce the complexity of either the configuration or its interface then a Terraform module SHOULD be used.
- Resources that have an aligned business purpose/requirement SHOULD be grouped together as a Terraform module.
- Resources that MUST satisfy multiple use cases SHOULD be created as a Terraform module.
- When a group of resources shares a similar lifecycle they SHOULD be grouped together as a Terraform module.
- If a resource is always going to be consumed by a higher-order module it SHOULD NOT be created as a bare/wrapper Terraform module.