Playing with Terraform graph

Let's play around with our VPC a bit to better understand how resource dependencies are handled. Instead of adding a subnet, let's destroy complete infrastructure we have so far and then plan creation from scratch:

$> terraform destroy
$> terraform plan
      # ... 
+ aws_subnet.public
    availability_zone:       "<computed>"
    cidr_block:              "10.0.1.0/24"    map_public_ip_on_launch: "false"
    vpc_id:                  "${aws_vpc.my_vpc.id}"
# ...

Terraform doesn't know the VPC ID yet, so it doesn't show it to you in the plan. Let's apply the template and observe the order of resource creation:

$> terraform apply
aws_vpc.my_vpc: Creating...
  cidr_block:                "" => "10.0.0.0/16"
  default_network_acl_id:    "" => "<computed>"
  default_security_group_id: "" => "<computed>"
  dhcp_options_id:           "" => "<computed>"
  enable_classiclink:        "" => "<computed>"
  enable_dns_hostnames:      "" => "<computed>"
  enable_dns_support:        "" => "<computed>"
  instance_tenancy:          "" => "<computed>"
  main_route_table_id:       "" => "<computed>"
aws_vpc.my_vpc: Creation complete
aws_subnet.public: Creating...
  availability_zone:       "" => "<computed>"
  cidr_block:              "" => "10.0.1.0/24"
  map_public_ip_on_launch: "" => "false"
  vpc_id:                  "" => "vpc-8f8568e7"
aws_subnet.public: Creation complete

Terraform knew (from the graph it built) that subnet requires VPC to exist, so it created it first, followed by subnet.

What happens if we recreate the VPC? Let's try it out with the help of the taint command. terraform taint marks a single resource for recreation. The resource will be destroyed and then created again.

$> terraform taint aws_vpc.my_vpc   
The resource aws_vpc.my_vpc in the module root has been marked as tainted!
$> terraform plan
-/+ aws_subnet.public
    availability_zone:       "eu-central-1b" => "<computed>"
    cidr_block:              "10.0.1.0/24" => "10.0.1.0/24"
    map_public_ip_on_launch: "false" => "false"
   vpc_id:                  "vpc-8f8568e7" => "${aws_vpc.my_vpc.id}" (forces new resource)
-/+ aws_vpc.my_vpc (tainted)
    cidr_block:                "10.0.0.0/16" => "10.0.0.0/16"
    default_network_acl_id:    "acl-a52febcd" => "<computed>"
    default_security_group_id: "sg-feafde96" => "<computed>"
    dhcp_options_id:           "dopt-b82bc8d1" => "<computed>"
    enable_classiclink:        "" => "<computed>"
    enable_dns_hostnames:      "false" => "<computed>"
    enable_dns_support:        "true" => "<computed>"
    instance_tenancy:          "default" => "<computed>"
    main_route_table_id:       "rtb-1913d071" => "<computed>"

Note

You might have noted it already: In Terraform outputs, - means resource will be destroyed, -/+ means recreation, and + is for creation.

Terraform got us covered: after recreating a VPC, it will also recreate a subnet because it knows that subnet depends on the VPC to exist. As AWS doesn't allow to simply change the VPC ID of existing subnet, Terraform will force the creation of the completely new subnet.

Which parameters the resource will use depends on provider implementation. Normally, it is mentioned in the Terraform documentation page for a specific resource.

If you try to draw a graph again, you won't see much difference from the previous one. The special destroy nodes are not included by default, and in order to see them, you need to specify the -verbose argument:

$> terraform graph -verbose | dot -Tpng > graph.png
Playing with Terraform graph

Note

As of Terraform version 0.8.2, the -verbose flag seems to be either broken or temporally disabled and doesn't actually draw destroy nodes. The source code for this flag is still there, deep inside Terraform. The preceding diagram was generated with Terraform 0.7.2.

Now we can see one node of the graph for the existing resource and another node to destroy it. Nodes are added to the graph in an order that will lead to the correct removal of resources that needs to be removed.

Before we finish with graphs, let's take a quick look at how dependencies are specified inside state file:

"aws_subnet.public": { 
    "type": "aws_subnet", 
    "depends_on": [ 
        "aws_vpc.my_vpc" 
       ], 
     "primary": { 
     "id": "subnet-2116e25b", 
     "attributes": { 
            "availability_zone": "eu-central-1b", 
            "cidr_block": "10.0.1.0/24", 
            "id": "subnet-2116e25b", 
            "map_public_ip_on_launch": "false", 
            "tags.%": "0", 
            "vpc_id": "vpc-8f8568e7" 
        }, 
        "meta": {}, 
        "tainted": false 
      }, 

Note the depends_on part--Terraform saves references to resources, and this one depends on inside this key. Most of the time, dependencies in Terraform just work. You just need to reference resources inside the template, and Terraform will do the job of building a graph and order operations with it. But sometimes, you need a little bit more control over the dependencies.

Note

There is another advantage of graphs inside Terraform--it allows you to process nodes in parallel if they don't depend on each other. By default, up to 10 graph nodes can be processed in parallel. You could specify the -parallelism flag for apply, plan, and destroy commands, but it's rather an advanced operation, and in most cases, you don't need it.

..................Content has been hidden....................

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