Controlling dependencies with depends_on and ignore_changes

In 99% of cases, Terraform will resolve dependencies automatically. There are two problems you can encounter when you rely solely on automatic resolution:

  • Dependency is not automatically handled by Terraform
  • Dependency leads to unwanted behavior and should be omitted

For both problems, there is a solution in Terraform. Let's first look at how you can force dependencies with depends_on. For each resource, you can specify the depends_on parameter, which accepts a list of resources that this resource depends on. As a result, this resource won't be created until the ones listed inside this parameter are created.

There might be different use cases for this. For example, your private OpenStack installation could be implemented in a way that it is impossible to create virtual routers in parallel, so you have to force dependency for each router to force Terraform to create them one after another. Or your instances could depend on the existence of one central master instance (which could be Chef Server or Puppet Master). Let's implement this scenario in our template.

Add two new resources to template.tf:

    resource "aws_instance" "master-instance" {
      ami = "ami-9bf712f4"
      instance_type = "t2.micro"
      subnet_id = "${aws_subnet.public.id}"
    }
    resource "aws_instance" "slave-instance" {
      ami = "ami-9bf712f4"
      instance_type = "t2.micro"
      subnet_id = "${aws_subnet.public.id}"
      depends_on = ["aws_instance.master-instance"]
    }

Draw the graph:

$> terraform graph | dot -Tpng > graph.png 

Controlling dependencies with depends_on and ignore_changes

Let's remove depends_on for the slave instance and draw graph again:

Controlling dependencies with depends_on and ignore_changes

With depends_on, all resources would be created sequentially. Without it, both EC2 instances will be created in parallel.

Note

Don't be too confused about the root circle. We will talk about what it is in a couple of minutes.

Now, let's say we want to include a private hostname of master in the list of tags of the slave, but we don't want to update it if master was recreated. To achieve this, we will use the ignore_changes parameter. This parameter is part of lifecycle block, responsible for few other create/destroy-related parameters. The ignore_changes parameter accepts the list of parameters to ignore when updating, in our case -tags:

resource "aws_instance" "slave-instance" { 
  ami = "ami-9bf712f4" 
  instance_type = "t2.micro" 
  subnet_id = "${aws_subnet.public.id}" 
  tags { 
    master_hostname = "${aws_instance.master-instance.private_dns}" 
  } 
  lifecycle { 
   ignore_changes = ["tags"] 
  } 
} 

Run the terraform apply command, then remove the tags parameter from the aws_instance.slave instance configuration and run the terraform plan command. Terraform will show you that there is nothing to do because it was told to ignore changes of the tags parameter.

Note

The most common use case for ignore_changes is, perhaps, user_data for cloud instances. For most providers, if you change user_data (the script to be executed on instance creation by the cloud-init utility), Terraform will try to recreate the instance. It is often unwanted behavior because most likely you use the same user_data string for multiple instances and you want changes to be applied only for new instances, while keeping the others running (or by recreating them one by one yourself).

With depends_on and ignore_changes, you can achieve a bit more flexibility when dealing with dependencies inside Terraform.

There are two other lifecycle block parameters that should be mentioned:

  • The create_before_destroy boolean parameter allows us to tell Terraform to first create new resource and then destroy previous one in case of recreation.
  • The prevent_destroy parameter, also boolean, marks resource as indestructible and can save you some nerves. One example of a resource that can benefit from this option is an Elastic IP--a dedicated IP address inside AWS than you can attach to an EC2 instance.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.139.50