Point solution infrastructure as code (IaC) templates get very tiresome very fast, because they’re not reusable.
This problem is not unique to any one tool – I have experienced this same story play out with multiple tools and IaC languages at this point and it always goes something like this:
Alice creates an IaC template to wrap and deploy a pair of VMs that automates a vendor solution.
Alice’s template works great for that use case, but another use case comes along that Bob is working on and someone says “I think Alice had a template for that,” and Bob copies and pastes Alice’s solution into a new file and modifies.
This “copy and modify” approach to IaC loses all consistency over time, amongst other things…
What works far far better than the above situation is isolating the individual resources you need to make, say an AWS S3 Bucket or Azure Storage Account, and fully parameterizing templates around them (with sensible defaults, and perhaps with some hard-coded items like minimum TLS versions and encryption enabled that avoid some potential security mis-configurations) in a generic way that can be reused.
You should be thinking of your IaC templates as highly componentized and modularized and genericized and composable, and seek to build out a shared repository of these “modules” that you can then wrap with higher level templates that compose together into meaningful, reusable solutions.
What you’ll find with this approach is that modularizing with defaults will provide you with that layer of abstraction around a resource so that you don’t have to sift through each and every possible property and parameter, thus reducing the parameter set and the resulting cognitive load that it takes to deploy or use one of those modules in a higher level template.
Software engineers have often tossed around the acronym “DRY” which stands for “Don’t Repeat Yourself” – nowhere is that more applicable than IaC.
This approach takes a bit more up-front effort and thought about how to organize things, but once you establish the pattern, you’ll find that with this approach, you’re not recreating templates, and instead just making new parameters for existing ones as new use cases arise.