Terraform (Part 3) : Structure
I hope parts one and two of this series have got you interested in IaC and Terraform in particular. In part two, the configuration file we used was just one file. In that simple use case it made sense to do it that way but as you start building more complex deployments, it is advisable to split up the configuration into multiple files and folders.
Splitting the configuration script into multiple files has some benefits:
- Reduced possibility of an error affecting the whole infrastructure.
- When working in a team, team members can work on different areas of the configuration reducing the risk of git merge conflicts.
- Parts of the configuration code can be re-used in other environments, for example stage and production.
- The code is easier to maintain (at least for me).
Looking back at the configuration file we created in Part 2, I intentionally put in noticeable headers to sections. For big/complex deployments, consider creating files for each of these sections.
If you have different environments, a good folder structure will help keep all files organised.
With the configuration split into multiple files, we can use folders to group similar resource functions together. There is no hard and fast rule about this ( at least not one I am currently aware of ) so as you build you will come up with a form of separation that works best for your environment. One general trend is to first have folders for each environment, for example Development, Staging and Production. Then within these folders you create folders for high level groupings of your deployment structure or requirements. For example you could have a folder for configuration that might affect the whole region. Another folder for services you plan deploying and maybe a third folder for custom code you might be using for your deployment.
Things affecting the whole region could be things like firewall rules, networking/IP addressing etc. Also services you plan rolling out could be grouped under a parent services folder, which for example, could contain subfolders for the configuration for databases, media servers, SIP proxies etc.
I have not mentioned modules so far in this series, hopefully I will do a write up on it. Modules are basically, your reusable custom code for certain functions or setups that are specific to your environment. Having one folder for all this custom code is also a good idea.
With this form of separation of code, you might end up in a situation where one configuration file would need information that was created by another configuration file. Say for example we created a specific network subnet we wanted to use for a set of servers. To get this information, it is possible to query your infrastructure for the data you need. The data ‘queries’ that are possible for a specific provider are found under ‘Data Sources’ of that provider. All such Data Source queries needed by the configuration of a resource can also be put in its own configuration file.
With all these considerations, your directory structure could look something like this
I encourage you to start thinking in this direction as you create your Terraform configuration files because as your deployment starts growing it will make things easier to maintain.