Terraform Null Resource

How to use Terraform Null Resource – Examples!

Terraform Null Resource it’s one of the several features that Terraform provides us. Once you have learned how to use null_resource, it’s mind-blowing because you immediately visualize several possibilities to use it to resolve complex problems and provisioning your resources.

In this article, you will see a list of examples in which you can find inspiration on how to use the Terraform Null Resource.

What is Terraform Null Resource?

The name may already suggest the Null Resource that when you are using this Terraform resource, you are not handling a physical resource in the cloud.

The null_resource helps us to execute any command remotely or locally to provisioning any resource or even to create a configuration file or perform some command or scripts to change some configuration. There is no limit to what you can do, which is powerful. 

How Terraform Null Resource Works?

Also, it’s essential to understand how to use the Terraform provisioner and triggers, which are used with null_resource, and then you will know how to use the Null Resouce.

It’s worth highlighting that you can use null_resource on:

1- Terraform Module

2- Combine with Terraform Count

3- Terraform Data

4- Terraform Local Variables

5- You can use the null_resource on Output.

6- You can also use null_resource with Conditional and Dynamic Expression

See this example:

resource "null_resource" "configmap" {
  
  triggers = {
    value = var.some_id
  }

  provisioner "local-exec" {
    command = <<EOT
      kubectl apply -f ${local.configmap_auth_file} --kubeconfig ${var.kubeconfig_path}
    EOT
  }
}

Inside the null_resource block, you can see the triggers. 

What does the triggers inside the null_resource block?

Inside the triggers, you can specify any key and value. The Terraform doesn’t care about the naming here. What matters is when those values change. When the values changes, Terraform will know when to execute this block again.

Like a regular resource, it also leaves in the Terraform State but doesn’t deploy anything on the cloud. Instead, it only uses the regular Terraform lifecycle, nothing more.

Terraform Provisioner

Inside the Null Resource block, you must specify what and where Terraform Provisioner will execute your commands. In other words, remotely or locally, and which steps?

The example above uses the Terraform provisioner “local-exec”, meaning that Provisioner will execute the command locally.

Examples of How to use Terraform Null Resource

In summary, the example above executes a command from Kubernetes (kubectl) to deploy and create a ConfigMap. 

It’s very useful, for example, if you are deploying one AWS EKS and your cluster depends on the specific ConfigMap, once your Terraform deploys the EKS cluster, the configmap will be automatically deployed along with the cluster.

The best way to explain using the Terraform null_resource is by presenting real examples. Let’s go deep.

Another crucial trick to learning how to use null_resource is to know how to wait for something to be created. For example, you only can call the terraform Provisioner when your EKS cluster is already created and running. Otherwise, the provisioning will fail.

How to wait for some resource to execute the null_resource?

You can use the depends_on inside the null_resource block like you do for any other regular resource.

resource "null_resource" "configmap" {
  
  triggers = {
    value = var.some_id
  }

depends_on = [aws_eks_cluster.my_cluster]

  provisioner "local-exec" {
    command = <<EOT
      kubectl apply -f ${local.configmap_auth_file} --kubeconfig ${var.kubeconfig_path}
    EOT
  }
}

Now, our example looks better. It will automatically wait for the EKS cluster to be created and execute our Terraform null_resource block.

Let’s see more examples and boost your learning process even further.

How to execute Terraform Null Resource only a file change?

You can quickly identify if one file was changed by using the md5, which produces the hashcode of a file.


resource "local_file" "backup_file" {
  content = templatefile("${path.module}/config.tpl", {
    host   = var.host
  })
  filename = "${path.module}/config.yml"
}

resource "null_resource" "backup_file" {
  triggers = {
    file_changed = md5(local_file.backup_file.content)
  }

  provisioner "local-exec" {
    command = "kubectl apply -f ${path.module}/config.yml"
  }

  depends_on = [local_file.backup_file]
}

So, every time the md5(local_file.backup_file.content) returns a different value, the null_resource will trigger the Provisioner and execute whatever required command.

How to always trigger the Terraform null_resource?

Sometimes, you may desire your terraform, Provisioner to always be triggered when executing the Terraform Plan or Terraform Apply, regardless of the trigger value. 

How to do it? Let’s see how it’s easy always to trigger the Provisioner.

Example:

resource "null_resource" "configmap" {
  
  triggers = {
    always_run = "${timestamp()}"
  }

  provisioner "local-exec" {
    command = <<EOT
      cat << EOF > /tmp/config
  REDIS_URL: "${data.remote_state.get.outputs.redis_primary_endpoint}:6379"
  KAFKA_CONSUMERS_BOOTSTRAP_SERVERS: "${data.remote_state.get.outputs.msk_bootstrap_brokers}"
 
EOF
    EOT
  }
}

Cool, tricky, Humm?

Every time you execute the Terraform, you will always generate a date (timestamp), so it will force the Provisioner to rerun the commands.

You also may have noticed in the example above the null_resource is only creating a file in your local computer, which you can use later for any proposal.

You can implement the reverse logic too:


resource "null_resource" "config" {
  provisioner "local-exec" {
    command = "kubectl apply -f ${path.module}/config.yaml"
  }
  depends_on = [kubernetes_namespace.app, local_file.app]
}

In the example above, you can see that there are no triggers.

What will happen in this example above?

The first time you execute, Terraform will create an entry on the Terraform State and execute that command inside the Provisioner. However, nothing will happen when you rerun the Terraform, so it will never call the null_resource again.

It’s helpful for scenarios to deploy configuration files or anything that doesn’t support duplication.

Those examples will help you a lot. If not, let me know, or if you have an excellent example you can contribute to our article will be very welcome!

Nice to see you again!

4 thoughts on “How to use Terraform Null Resource – Examples!”

  1. Thank you. These are nice examples. Each of the examples above has provisioner in it. I have seen some examples where triggers is present but no provisioner. Can you suggest when to go with this approach?

  2. Vladimir Frometa

    Thanks for sharing this useful post, it is thorough, well explained, and insightful. There is a lot of power in there, where you can combine dependencies on these null-resources to have mor control over conditionally provisioning infrastructure, plus, subsequent actions. Thanks again, you gave me the primer for a solution that I am working on.

Leave a Comment

Your email address will not be published. Required fields are marked *

Free PDF with a useful Mind Map that illustrates everything you should know about AWS VPC in a single view.