Network drivers are used by Consul-Terraform-Sync to execute and update network infrastructure. Drivers transform Consul service level information into downstream changes by understanding and abstracting API and resource details tied to specific network infrastructure.
## Terraform
Consul-Terraform-Sync is a HashiCorp solution to Network Infrastructure Automation by bridging the networking features of Consul and infrastructure management with Terraform. The solution seamlessly embeds Terraform as a network driver to manage automation of Terraform modules. This expands the Consul ecosystem and taps into the rich features and community of Terraform and Terraform providers. Consul-Terraform-Sync automates Terraform execution of templated configuration files to carry out infrastructure changes. The auto-generated configuration leverages input variables sourced from Consul and builds on top of reusable Terraform modules published and maintained by HashiCorp partners and the community.
### Understanding Terraform Automation
On startup, Consul-Terraform-Sync downloads and installs [Terraform](https://www.terraform.io/downloads.html), prepares the local environment, and generates Terraform configuration files that make up the root module for each task. Terraform configuration and execution for each task is organized as separate [Terraform workspaces](https://www.terraform.io/docs/state/workspaces.html). The state files for tasks are independent of each other.
~> **Note:** Although Terraform state files for task workspaces are independent, this does not guarantee the infrastructure changes from concurrent task executions are independent. Ensure that modules across all tasks are not modifying the same resource objects or have overlapping changes that may result in race conditions during automation.
Within the Consul-Terraform-Sync configuration for a task, practitioners can select the desired module to run for the task as well the set of services for the module to execute on. Each task executed by the Terraform driver corresponds to an automated root module that calls the selected module in an isolated Terraform environment. Consul-Terraform-Sync will manage concurrent execution of these tasks.
### Root Module
The root module is simple in structure and proxies Consul service information, configuration, and other variables to the Terraform module for the task. The content of the files that make up the root module are sourced from Consul-Terraform-Sync configuration, information for task's module to use as the automation playbook, and the Consul catalog for discovering service information.
Autogenerated root modules for tasks are stored in local subdirectories of the Terraform working directory. By default, the working directory `sync-tasks` is created in the current directory. To configure where Terraform configuration files are stored, set [`working_dir`](/docs/nia/configuration#working_dir) for the Terraform driver to the desired path.
A working directory with one task named "my-task" would have the folder structure below.
```
sync-tasks/
my-task/
main.tf
variables.tf
terraform.tfvars
terraform.tfvars.tmpl
```
The following files of the root module are generated for each task. An [example of a root module created by Consul-Terraform-Sync](https://github.com/hashicorp/consul-terraform-sync/tree/master/examples) can be found in the project repository.
* `main.tf` - The main file contains the terraform block, provider blocks, and a module block calling the module configured for the task.
* `terraform` block - The corresponding provider source and versions for the task from the configuration files are placed into this block for the root module. The Terraform backend from the configuration is also templated here.
* `provider` blocks - The provider blocks generated in the root module resemble the `terraform_provider` blocks in the configuration. They have identical arguments present and are set from the intermediate variable created per provider.
* `module` block - The module block is where the task's module is called as a [child module](https://www.terraform.io/docs/configuration/modules.html#calling-a-child-module). The child module contains the core logic for automation. Required and optional input variables are passed as arguments to the module.
* `variables.tf` - This file contains 2 types of variable declarations. The required `services` input variable which determines module compatibility with Consul-Terraform Sync (read more on [compatible Terraform modules](/docs/nia/installation/requirements#how-to-create-a-compatible-terraform-module) for more details) and various intermediate variables used to dynamically configure providers. These intermediate provider variables are interpolated from the provider blocks and arguments configured in the Consul-Terraform-Sync configuration.
* `variables.module.tf` - This file is conditionally created if there are [variables configured for the task](/docs/nia/configuration#variable_files) and contains the interpolated variable declarations that match the variables from configuration. These are then used to proxy the configured variables to the module through explicit assignment in the module block.
* `terraform.tfvars` - The variable definitions file is where the services input variable is assigned values from the Consul catalog. It is periodically updated to reflect the current state of the configured set of services for the task.
* `terraform.tfvars.tmpl` - The template file is used by Consul-Terraform-Sync to template service information from the Consul catalog by using the HashiCorp configuration and templating library ([hashicorp/hcat](https://github.com/hashicorp/hcat)).
-> **Note:** Generated template and Terraform configuration files are crucial to the automation of tasks. Any manual changes to the files may not be preserved and could be overwritten by a subsequent update.