Terraform - what is null provider?

Viewed 4756

I am wondering what is the real use of terraform null provider and when to use and NOT use it.

I have gone through the Terraform docs - https://registry.terraform.io/providers/hashicorp/null/latest/docs but it has been of little help.

Null Provider

The null provider is a rather-unusual provider that has constructs that intentionally do nothing. This may sound strange, and indeed these constructs do not need to be used in most cases, but they can be useful in various situations to help orchestrate tricky behavior or work around limitations.

The documentation of each feature of this provider, accessible via the navigation, gives examples of situations where these constructs may prove useful.

Usage of the null provider can make a Terraform configuration harder to understand. While it can be useful in certain cases, it should be applied with care and other solutions preferred when available.

Could some one eloborate on - but they can be useful in various situations to help orchestrate tricky behavior or work around limitations. And provide further references to explore this provider.

-- this is how my providers.tf file looks -

provider "aws" {
  alias   = "primary"
  region  = "us-east-1"
  profile = "${local.primary_aws_profile}"
  version = "~> 2.70.0"
}

provider "template" {
  version = "~> 1.0"
}

provider null {
  version = "~> 1.0"
}
2 Answers

Could some one eloborate on - but they can be useful in various situations to help orchestrate tricky behavior or work around limitations. And provide further references to explore this provider.

@Marcin answer outlines an example using a null_resource with local-exec and I thought I'd expand with a concrete example of when I have had to use one with remote_exec.

I had an issue where I was unable to destroy an EC2 aws_instance that had an aws_volume_attachment because the EBS volume was not detached prior to destroying. The workaround was to use a null_resource to unmount the volume on destroy of the instance and volume attachment.

resource "aws_instance" "instance" { ..snip .. }

resource "aws_ebs_volume" "data" { ..snip.. }

resource "aws_volume_attachment" "data_att" {
  device_name  = "/dev/sdf"
  volume_id    = aws_ebs_volume.data.id
  instance_id  = aws_instance.instance.id
}

resource "null_resource" "unmount_data_drive" {
  triggers = {
    public_ip = aws_instance.instance.public_ip
  }

  depends_on = [aws_volume_attachment.data_att, aws_instance.instance]

  provisioner "remote-exec" {
    when       = destroy
    on_failure = continue
    connection {
      type        = "ssh"
      agent       = false
      host        = self.triggers.public_ip
      user        = "ubuntu"
      private_key = file(var.key_pair)
    }
    inline = [
      "sudo umount /opt/data",
      "sudo sed -i '/opt\\/data/d' /etc/fstab"
    ]
  }
}

You are using null resource primary null_resource:

The primary use-case for the null resource is as a do-nothing container for arbitrary actions taken by a provisioner.

As the description writes, you use it mostly with provisioners such as local-exec and remote-exec.

A common scenario is to perform custom actions using local-exec and remote-exec when a number of resources gets created. Example of such case is introduction of a delay in resource creation, as shown here:

resource "null_resource" "before" {
}

resource "null_resource" "delay" {
  provisioner "local-exec" {
    command = "sleep 10"
  }
  triggers = {
    "before" = "${null_resource.before.id}"
  }
}

resource "null_resource" "after" {
  depends_on = ["null_resource.delay"]
}
Related