Photo by Mukund Nair on Unsplash

How to conditionally disable modules in Terraform for different environments

pascal.brokmeier
Sep 27 · 2 min read

Terraform doesn’t support the count parameter on modules. A proposal was made for a enabled parameter, but this is also not yet present. Therefore, it appears to be hard to conditionally disable terraform modules. There’s a dirty hack to put count parameters on all the resources inside the module. Yet, this is veeery messy.

If we take a step back and think about when we actually want to do this, it is typically a use case for e.g. a dev environment. These environments have a different tfvars input file associated with them and therefore a developer may want to do something like

enabled = var.env == "prd" ? true : false

Yet, this is not possible in terraform as of today. Yet, below is a solution for still enabling / disabling modules for different environments.

See my other post for an overview of our folder structure for several environments which enables this trick. Our current setup is also shown below:

.
├── deploy.sh
├── destroy.sh
├── dev
│ ├── infra_override.tf
│ ├── infra.tf -> ../universal/infra.tf
│ ├── output.tf -> ../universal/output.tf
│ ├── state.tf
│ ├── terraform.tfvars
│ └── variables.tf -> ../universal/variables.tf
├── prd
│ ├── infra.tf -> ../universal/infra.tf
│ ├── output.tf -> ../universal/output.tf
│ ├── state.tf
│ ├── terraform.tfvars
│ └── variables.tf -> ../universal/variables.tf
├── symlink.sh
├── tst
│ ├── infra_override.tf
│ ├── infra.tf -> ../universal/infra.tf
│ ├── output.tf -> ../universal/output.tf
│ ├── state.tf
│ ├── terraform.tfvars
│ └── variables.tf -> ../universal/variables.tf
└── universal
├── infra.tf
├── output.tf
└── variables.tf

The infra.tf file contains all the code we share across environments. Let’s say we have a module “gitlab” which we don’t want to deploy to an environment to preserve resources.

First, we define the module as usual in our infra.tf file.

module "gitlab" {
source = "../../modules/gitlab"
artifacts_bucket = module.account.artifacts_bucket
cicd_role = local.cicd_role
eks_cluster_name = module.kubernetes.k8s_cluster_name
environment = var.environment
...
}

Now, in the infra_override.tf file of our dev/tst/... environments, we define the following lines to avoid deploying the module to these environments

#no deployment of gitlab on the tst cluster needed
module "gitlab"{
source = "../../modules/empty-module"
}

This override file gets merged with the infra.tf file by terraform. The empty-module is exactly what it suggests. A folder with an empty nothing.tf file, simply explaining why it exists.

Warning Edit: I realized this after posting this but the empty module actually requires a file that defines the same variable definitions as the original module. This means one must create an “empty” module version for each module that one wants to conditionally enable. I suggest putting an empty folder inside of the module code that links to the parent’s vars.tf file.

Result: The ability to “conditionally enable a terraform module”. It’s a hack, but it works and it’s pretty easy to understand.

datamindedbe

Better data engineering

pascal.brokmeier

Written by

Software Developer, Tech enthusiast, student, board sports and food lover

datamindedbe

Better data engineering

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade