Introduction

With terraform 0.13 comes the little but big feature from HashiCorp, which wasn’t enabled on the previous terraform versions: conditions & dependencies on modules. In this short article, I’ll compare terraform 0.13 to its previous version: 0.12 and will show you why you shouldn’t start from an older version.

Module conditions

terraform 0.12

If you’ve played a little bit with Terraform and tried to implement some logic to your code – you surely have faced an annoying limitation: No count conditions in Modules. Fortunately (but very messy), there was a workaround for this issue: pass a parameter to the module and use it as a flag of ‘true’ or ‘false’. Then, you can use it on any resource you’re creating, using the count condition.

Module condition workaround – terraform 0.12

First, lets use the module and inject a parameter which called ‘cluster_provision’:

module "eks" {
    source = "./develeap_eks"
    cluster_name = var.cluster_name
    region = var.aws_region
    provision_cluster = var.provision_cluster
}

Then, we’ll need to use it on EVERY RESOURCE under the module, in order to make a condition for the whole module:

resource "aws_eks_cluster" "cluster" {
  count    = var.provision_cluster ? 1 : 0 #Check if cluster provisioning is enabled
  name     = var.cluster_name
  #...
  # More cluster configuration here
  #...
}

resource “aws_eks_node_group” “nodegroup” {
  count    = var.provision_cluster ? 1 : 0 #Check if cluster provisioning is enabled
  cluster_name    = var.cluster_name
 node_group_name = “nodegroup_a”
  #…
  # More nodegroup configuration here
  #…
}

terraform 0.13

Happily, now in terraform 0.13, we can use count conditions directly in our modules. No need for any workarounds anymore. No more ‘spams’ in all of our resources declarations. Just one count condition in our module:

module "eks" {
    count        = var.provision_cluster ? 1 : 0
    source       = "./develeap_eks"
    cluster_name = var.cluster_name
    region       = var.aws_region
}

Module dependencies

terraform 0.12

Sometimes, you’ll want to use module A before module B. Sometimes you will want to create some dependencies between your modules. On the previous terraform version (0.12) you had to do a DIRTY workaround in order to create dependencies between your modules (taken from this GitHub issue).

Firstly, add a “dependencies” variable to all your modules:

variable "dependencies" {
  type = "list"
}

Then, add the following “dependency_getter” to all your modules:

resource "null_resource" "dependency_getter" {
  provisioner "local-exec" {
    command = "echo ${length(var.dependencies)}"
  }
}

Then, add the following “depends_on” to all your resources under the relevant module:

depends_on = [
  "null_resource.dependency_getter"
]

Then, add the following “output” to all your modules:

output "depended_on" {
  value = null_resource.dependency_getter.id
}

And after all this, it allows me to use a dependency like this:

module "my_module" {
  source           = "./develeap_module"
  dependencies = [
    "${module.eks.depended_on}",
  ]
}

terraform 0.13

How about a simple depends_on instead of the horrible workaround above? simply:

module "eks" {
    count        = provision_cluster ? 1 : 0
    source       = "./develeap_eks"
    cluster_name = var.cluster_name
    region       = var.aws_region
    depends_on   = [
      module.ec2_module
    ]
}

To sum up, the little improvements that HashiCorp has made on Terraform 0.13 made our life much easier, as we can easily add logic to our modules inside our terraform code.