Terraform is a great tool to provision and maintain multiple environment with identical resources (with some configuration changes). The capability to use same terraform IaC for multiple environment helps teams deploy infrastructure and maintain consistency. A common way to provide provide environment specific values for resources is leveraging terraform .tfvars files.
tfvars file
Terraform tfvars files are common way to pass environment specific values for variables in key value pairs. This approach is very efficient for managing multiple environments with similar resources.
This method can help with creating resources with different configuration’s (naming, SKU, tags etc) but what if we want to create resources in only one environment without adding to terraform configurations.
When we want multiple environments with exact same set of resources we can leverage “environment”.tfvars. This is fairly simple way to achieve consistency and maintain infrastructure as code (IaC).
The Challenge
The method discussed above is suitable approach where the same resources are needed in all environments (which is rarely the case). For teams trying to introduce new resources it becomes evident that some resources are needed only in one or two environment and not on others.
How to manage such a scenario where a resource is needed only in “dev” environment. The following sections explores what approaches can be taken for such situations.
Approach 1: add conditional logic for environment
One way is to use terraform count or for_each to create resources based on environment variable. This is commonly used approach. Personally prefer for_each rather than count just because we are restricted by sequencing in count (count deleted resources just because a developer added a value in the middle of the list variable). Hence its recommended to use for_each instead of count.
https://developer.hashicorp.com/terraform/language/meta-arguments/count
count and for_each
for_each for map variable
Issues:
While for a small configuration this approach is maintainable but it becomes a hassle as the IaC scope expands. With addition of new resources and for projects working on adding new resources frequently it becomes difficult to manage.
Approach 2: Build folder approach
Another approach can be to maintain environment specific resources in different configuration files. This approach reduces the effort to maintain condition logic in terraform code.
- Create folder containing common terraform resources
- Create folder with environment specific resources. This way we do not need to add any conditions in terraform logic.
- Finally create a build folder by merging both folders.
- Finally run terraform plan command inside the build folder.
cd build/dev1 terraform plan
I hope you find this approach suitable for your workloads, do suggest me if you are leveraging a better approach to manage these scenarios.