terraform null resource - ghdrako/doc_snipets GitHub Wiki

null_resource

  1. Is useful when we need to do something that is not directly associated with the lifecycle of an actual resource ex running scripts, update instance
  2. Within a null_resource, you can configure provisioners to run scripts to do pretty much whatever you want ex ssh to instance and run a command or connect to a database to execute a query, or simply run a script to register an instance with DNS,
  3. Just like provisioners, it is a googd idea to use null_resource sparingly (rarry) since it adds to the complexity of Teraform usage
  4. test it

Actions that are done inside a null_resource are nto managed by Terraform. If you decide to call a command to create resources in your null_resource, Terraform will not know about the resource creation and therefore can't manage its lifecycle and state.

The triggers parameter allows the resource to respond to changes, causing the resource to be destroyed & recreated, impacting on any dependencies or attached provisioners. Without trigger null-resource haven't make sense because doesn’t actually manage any underlying item.

Example

Trigger argument allowes us to specyfy arbitrary set of values that when change , will cause a resource to be replaced. In this examle when instanses id will change then "remote-exec" provide will be re-run on instances of the cluster required reprovisioning. In bootstrap script run on any instance onf the cluster.

resource "aws_instance" "prod_cluster" {
  count = 4
# ...
}

resource "null_resource" "prod_cluster" {
  triggers = {
    cluster_instance_ids = join("," aws_instance.prod_cluster.*.id)
  }
  connection {
    host = element(aws_instance.prod_cluster.*.public_ip, 0)
  }
  provisioner "remote-exec" {
    inline = [
      "prd_cluster.sh ${join(" ", aws_instance.prod_cluster.*.provate_ip)}",
    ]
  }
}

#aws instance creation
resource "aws_instance" "os1" {
  ami           = "ami-010aff33ed5991201"
  instance_type = "t2.micro"
  security_groups =  [ "launch-wizard-3" ]
   key_name = "mykey1122"
  tags = {
    Name = "TerraformOS"
  }
}


#IP of aws instance retrieved
output "op1"{
value = aws_instance.os1.public_ip
}


#IP of aws instance copied to a file ip.txt in local system
resource "local_file" "ip" {
    content  = aws_instance.os1.public_ip
    filename = "ip.txt"
}


#connecting to the Ansible control node using SSH connection
resource "null_resource" "nullremote1" {
depends_on = [aws_instance.os1] 
connection {
	type     = "ssh"
	user     = "root"
	password = "${var.password}"
    	host= "${var.host}" 
}
#copying the ip.txt file to the Ansible control node from local system
provisioner "file" {
    source      = "ip.txt"
    destination = "/root/ansible_terraform/aws_instance/ip.txt"
  		   }
}