website: don't talk about graphs in the Getting Started guide

Previously we just assumed the reader was familiar with the idea of a
graph but didn't explain it.

Since graphs are an implementation detail of Terraform, rather than
essential information needed for new users, this revises the introduction
text to talk only about _dependencies_, which we assume the user is
familiar with as a more practical concept.

Additionally, Paul Hinze did a great talk on how Terraform uses graphs
at HashiConf 2016 which is good additional content for our existing
"Graph Internals" page, which includes a concise explanation of the
basics of graph theory.
This commit is contained in:
Martin Atkins 2017-09-08 15:38:45 -07:00
parent 9504d17bd9
commit 93651450b1
2 changed files with 54 additions and 35 deletions

View File

@ -21,6 +21,12 @@ effectively use Terraform. The details are documented here for
those who wish to learn about them without having to go those who wish to learn about them without having to go
spelunking through the source code. spelunking through the source code.
For some background on graph theory, and a summary of how
Terraform applies it, see the HashiCorp 2016 presentation
[_Applying Graph Theory to Infrastructure as Code_](https://www.youtube.com/watch?v=Ce3RNfRbdZ0).
This presentation also covers some similar ideas to the following
guide.
## Graph Nodes ## Graph Nodes
There are only a handful of node types that can exist within the There are only a handful of node types that can exist within the

View File

@ -129,40 +129,52 @@ first.
## Implicit and Explicit Dependencies ## Implicit and Explicit Dependencies
Most dependencies in Terraform are implicit: Terraform is able By studying the resource attributes used in interpolation expressions,
to infer dependencies based on usage of attributes of other Terraform can automatically infer when one resource depends on another.
resources. In the example above, the expression `${aws_instance.example.id}` creates
an _implicit dependency_ on the `aws_instance` named `example`.
Using this information, Terraform builds a graph of resources. Terraform uses this dependency information to determine the correct order
This tells Terraform not only in what order to create resources, in which to create the different resources. In the example above, Terraform
but also what resources can be created in parallel. In our example, knows that the `aws_instance` must be created before the `aws_eip`.
since the IP address depended on the EC2 instance, they could
not be created in parallel.
Implicit dependencies work well and are usually all you ever need. Implicit dependencies via interpolation expressions are the primary way
However, you can also specify explicit dependencies with the to inform Terraform about these relationships, and should be used whenever
`depends_on` parameter which is available on any resource. For example, possible.
we could modify the "aws\_eip" resource to the following, which
effectively does the same thing and is redundant: Sometimes there are dependencies between resources that are _not_ visible to
Terraform. The `depends_on` argument is accepted by any resource and accepts
a list of resources to create _explicit dependencies_ for.
For example, perhaps an application we will run on our EC2 instance expects
to use a specific Amazon S3 bucket, but that dependency is configured
inside the application code and thus not visible to Terraform. In
that case, we can use `depends_on` to explicitly declare the dependency:
```hcl ```hcl
resource "aws_eip" "ip" { # New resource for the S3 bucket our application will use.
instance = "${aws_instance.example.id}" resource "aws_s3_bucket" "example" {
depends_on = ["aws_instance.example"] # NOTE: S3 bucket names must be unique across _all_ AWS accounts, so
# this name must be changed before applying this example to avoid naming
# conflicts.
bucket = "terraform_getting_started_guide"
acl = "private"
}
# Change the aws_instance we declared earlier to now include "depends_on"
resource "aws_instance" "example" {
ami = "ami-2757f631"
instance_type = "t2.micro"
# Tells Terraform that this EC2 instance must be created only after the
# S3 bucket has been created.
depends_on = ["aws_s3_bucket.example"]
} }
``` ```
If you're ever unsure about the dependency chain that Terraform
is creating, you can use the [`terraform graph` command](/docs/commands/graph.html) to view
the graph. This command outputs a dot-formatted graph which can be
viewed with
[Graphviz](http://www.graphviz.org/).
## Non-Dependent Resources ## Non-Dependent Resources
We can now augment the configuration with another EC2 instance. We can continue to build this configuration by adding another EC2 instance:
Because this doesn't rely on any other resource, it can be
created in parallel to everything else.
```hcl ```hcl
resource "aws_instance" "another" { resource "aws_instance" "another" {
@ -171,19 +183,20 @@ resource "aws_instance" "another" {
} }
``` ```
You can view the graph with `terraform graph` to see that Because this new instance does not depend on any other resource, it can
nothing depends on this and that it will likely be created be created in parallel with the other resources. Where possible, Terraform
in parallel. will perform operations concurrently to reduce the total time taken to
apply changes.
Before moving on, remove this resource from your configuration Before moving on, remove this new resource from your configuration and
and `terraform apply` again to destroy it. We won't use the run `terraform apply` again to destroy it. We won't use this second instance
second instance anymore in the getting started guide. any further in the getting started guide.
## Next ## Next
In this page you were introduced to both multiple resources In this page you were introduced to using multiple resources, interpolating
as well as basic resource dependencies and resource attribute attributes from one resource into another, and declaring dependencies between
interpolation. resources to define operation ordering.
Moving on, [we'll use provisioners](/intro/getting-started/provision.html) In the next section, [we'll use provisioners](/intro/getting-started/provision.html)
to do some basic bootstrapping of our launched instance. to do some basic bootstrapping of our launched instance.