Terraform Study Notes: Read, generate, and modify configuration pt.3

In the previous post related to this study notes, we analyzed expressions, collection, and structural types putting also into practice how to correctly address a resource in the configuration. Now it’s time to close the topic by explaining the usage of the data sources and how to deal with the dependencies map.

Create and differentiate data configuration

Data sources allow Terraform to use information defined outside of Terraform, defined by another separate Terraform configuration, or modified by functions.

Each provider may offer data sources alongside its set of resource types.

Let’s see it in practice (the following example is available in my GitHub repo under the directory example_5)… before applying the following config, type:

data block requests that Terraform read from a given data source (“docker_image”) and export the result under output “docker_image”

Each data resource is associated with a single data source, which determines the kind of object (or objects) it reads and what query constraint arguments are available.

Each data source in turn belongs to a provider, which is a plugin for Terraform that offers a collection of resource types and data sources that most often belong to a single cloud or on-premises infrastructure platform.

Most of the items within the body of a data block is defined by and specific to the selected data source, and these arguments can make full use of expressions and other dynamic Terraform language features

If the query constraint arguments for a data resource refer only to constant values or values that are already known, the data resource will be read and its state updated during Terraform’s “refresh” phase, which runs before creating a plan.

While many data sources correspond to an infrastructure object type that is accessed via a remote network API, some specialized data sources operate only within Terraform itself, calculating some results and exposing them for use elsewhere.

Data resources have the same dependency resolution behavior as defined for managed resources. Setting the depends_on meta-argument within data blocks defers reading of the data source until after all changes to the dependencies have been applied.

Data resources do not currently have any customization settings available for their lifecycle, but the lifecycle nested block is reserved in case any are added in future versions.

As data sources are essentially a read-only subset of resources, they also support the same meta-arguments of resources except for the lifecycle configuration block.:

Similarly to resources, when a module has multiple configurations for the same provider you can specify which configuration to use with the provider meta-argument

If the arguments of a data instance contain no references to computed values, such as attributes of resources that have not yet been created, then the data instance will be read and its state updated during Terraform’s “refresh” phase, which by default runs before creating a plan.

Describe built-in dependency management (order of execution based)

The most common source of dependencies is an implicit dependency between two resources or modules.

Implicit dependencies are the primary way that Terraform understands the relationships between your resources. Sometimes there are dependencies between resources that are not visible to Terraform, however. The depends_on argument is accepted by any resource or module block and accepts a list of resources to create explicit dependencies for.

Both implicit and explicit dependencies affect the order in which resources are destroyed as well as created.

Terraform builds a dependency graph from the Terraform configurations and walks this graph to generate plans, refresh state, and more.

There are only a handful of node types that can exist within the graph. We’ll cover these first before explaining how they’re determined and built:

  • Resource Node – Represents a single resource. If you have the count meta parameter set, then there will be one resource node for each count. The configuration, diff, state, etc. of the resource under change is attached to this node.

  • Provider Configuration Node – Represents the time to fully configure a provider. This is when the provider configuration block is given to a provider, such as AWS security credentials.

  • Resource Meta-Node – Represents a group of resources, but does not represent any action on its own. This is done for convenience on dependencies and making a prettier graph. This node is only present for resources that have a count parameter greater than 1.

When visualizing a configuration with terraform graph, you can see all of these nodes present.

Building the graph is done in a series of sequential steps:

  1. Resources nodes are added based on the configuration
  2. Resources are mapped to provisioners if they have any defined
  3. Explicit dependencies from the depends_on Meta-parameters are used to create edges between resources.

  4. If a state is present, any “orphan” resources are added to the graph
  5. Resources are mapped to providers
  6. Interpolations are parsed in resource and provider configurations to determine dependencies
  7. Create a root node
  8. If a diff is present, traverse all resource nodes and find resources that are being destroyed
  9. Validate the graph has no cycles and has a single root


   Send article as PDF