---
layout: docs
page_title: Consul-Terraform-Sync onfiguration
description: >-
  Consul-Terraform-Sync requires a Terraform Provider, a Terraform Module and a running Consul Cluster outside of the consul-terraform-sync daemon.
---

# Consul-Terraform-Sync configuration

This topic contains configuration reference information for Consul-Terraform-Sync (CTS). Pass configuration settings in an HCL or JSON configuration file to configure the CTS daemon. Refer to the [HashiCorp Configuration Language](https://github.com/hashicorp/hcl) to learn the HCL syntax.

## Global configurations

Top level options are reserved for configuring CTS.

```hcl
log_level   = "INFO"
working_dir = "sync-tasks"
port        = 8558
id          = "cts-01"

syslog {
  facility = "local2"
}

buffer_period {
  enabled = true
  min     = "5s"
  max     = "20s"
}

tls {
  enabled         = true
  cert            = "/path/to/cert.pem"
  key             = "/path/to/key.pem"
  verify_incoming = true
  ca_cert         = "/path/to/ca.pem"
}
```

- `buffer_period` - Configures the default buffer period for all dynamic [tasks](#task) to dampen the effects of flapping services to downstream network devices. It defines the minimum and maximum amount of time to wait for the cluster to reach a consistent state and accumulate changes before triggering task executions. The default is enabled to reduce the number of times downstream infrastructure is updated within a short period of time. This is useful to enable in systems that have a lot of flapping. Buffer periods do not apply to scheduled tasks.
  - `enabled` - (bool: true) Enable or disable buffer periods globally. Specifying `min` will also enable it.
  - `min` - (string: "5s") The minimum period of time to wait after changes are detected before triggering related tasks.
  - `max` - (string: "20s") The maximum period of time to wait after changes are detected before triggering related tasks. If `min` is set, the default period for `max` is 4 times the value of `min`.
- `log_level` - (string: "INFO") The log level to use for CTS logging. This defaults to "INFO". The available log levels are "TRACE", "DEBUG", "INFO", "WARN", and "ERR".
- `port` - (int: 8558) The port for CTS to use to serve API requests.
- `id` (string: Generated ID with the format `cts-<hostname>`) The ID of the CTS instance. CTS uses the ID as the service ID for CTS if service registration is enabled. CTS also uses the ID to identify the instance in a high availability cluster.
- `syslog` - Specifies the syslog server for logging.
  - `enabled` - (bool) Enable syslog logging. Specifying other option also enables syslog logging.
  - `facility` - (string: "local0") Name of the syslog facility to log to.
  - `name` - (string: "consul-terraform-sync") Name to use for the daemon process when logging to syslog.
- `working_dir` - (string: "sync-tasks") Specifies the base working directory for managing the artifacts generated by CTS for each task, including Terraform configuration files. CTS will also generate a subdirectory for each task, e.g., `./sync-tasks/task-name`. The subdirectory is the working directory for the task. Use the [`task.working_dir`](#working_dir-1) option to override task-level working directories.
- `tls` - Configure TLS on the CTS API.
  - `enabled` - (bool: false) Enable TLS. Providing a value for any of the TLS options will enable this parameter implicitly.
  - `cert` - (string) The path to a PEM-encoded certificate file used for TLS connections to the CTS API.
  - `key` - (string) The path to the PEM-encoded private key file used with the certificate configured by `cert`.
  - `verify_incoming` - (bool: false) Enable mutual TLS. Requires all incoming connections to the CTS API to use a TLS connection and provide a certificate signed by a Certificate Authority specified by the `ca_cert` or `ca_path`.
  - `ca_cert` - (string) The path to a PEM-encoded certificate authority file used to verify the authenticity of the incoming client connections to the CTS API when `verify_incoming` is set to true. Takes precedence over `ca_path` if both are configured.
  - `ca_path` - (string) The path to a directory of PEM-encoded certificate authority files used to verify the authenticity of the incoming client connections to the CTS API when `verify_incoming` is set to true.
- `license_path` <EnterpriseAlert inline /> - (string) **Deprecated in CTS 0.6.0 and will be removed in a future release. Use [license block](/consul/docs/automate/infrastructure/configure#license) instead.**  Configures the path to the file that contains the license. You must specify a license in order to use enterprise features. You can also set the license by defining the `CONSUL_LICENSE` and `CONSUL_LICENSE_PATH` environment variables. For more information, refer to [Setting the License](/consul/docs/nia/enterprise/license#setting-the-license).

## License <EnterpriseAlert inline />

The `license` block configures how CTS loads its license with options to:
- Configure CTS to automatically retrieve a license from Consul.
- Provide a path to a license file.

When a license block is not configured, CTS uses automatic license retrieval.

```hcl
license {
  path = "path/to/license.lic"
  auto_retrieval {
    enabled = true
  }
}
```

| Parameter | Required | Type | Description | Default |
| --------- | -------- | ---- | ----------- | ------- |
| `path` |  Optional | string | Configures the path to the file containing a license. If a path to a license is configured, this license is used until you enable automatic license retrieval. You can also set the license by defining the `CONSUL_LICENSE` and `CONSUL_LICENSE_PATH` environment variables. To learn more, review [Setting the License](/consul/docs/nia/enterprise/license#setting-the-license). | none |
| `auto_retrieval` |  Optional | object | Configures the license auto-retrieval used by CTS. To learn more, review [Auto-Retrieval](/consul/docs/automate/infrastructure/configure#auto-retrieval) for details | Review [Auto-Retrieval](/consul/docs/automate/infrastructure/configure#auto-retrieval) for defaults. |


### Auto-retrieval

You can use the `auto_retrieval` block to configure the automatic license retrieval in CTS. When enabled, CTS attempts to retrieve a new license from its configured Consul Enterprise backend once a day. If CTS cannot retrieve a license and the current license is reaching its expiration date, CTS attempts to retrieve a license with increased frequency, as defined by the [License Expiration Date Handling](/consul/docs/nia/enterprise/license#license-expiration-handling).

<Note>

Enabling `auto_retrieval` is recommended when using HCP Consul, as HCP Consul licenses expire more frequently than Consul Enterprise licenses. Without auto-retrieval enabled, you have to restart CTS every time you load a new license.

</Note>

| Parameter | Required | Type | Description | Default |
| --------- | -------- | ---- | ----------- | ------- |
| `enabled` |  Optional | string | If set to true, enables license auto-retrieval | true |

## Consul connection

The `consul` block configures the CTS connection with a Consul agent so that CTS can perform queries for task execution. It also configures the automatic registration of CTS as a service with Consul.

<Note>

Use HTTP/2 to improve Consul-Terraform-Sync performance when communicating with the local Consul process. [TLS/HTTPS](/consul/docs/reference/agent) must be configured for the local Consul with the [cert_file](/consul/docs/reference/agent/configuration-file/tls#cert_file) and [key_file](/consul/docs/reference/agent/configuration-file/tls#key_file) parameters set. For the Consul-Terraform-Sync configuration, set `tls.enabled = true` and set the `address` parameter to the HTTPS URL, e.g., `address = example.consul.com:8501`. If using self-signed certificates for Consul, you will also need to set `tls.verify = false` or add the certificate to `ca_cert` or `ca_path`.

</Note>

To read more on suggestions for configuring the Consul agent, refer to  [run an agent](/consul/docs/nia/usage/requirements#run-an-agent).

```hcl
consul {
  address = "localhost:8500"
  auth {}
  tls {}
  token = null
  transport {}
  service_registration {
    service_name = "cts"
    address = "172.22.0.2"
    default_check {
      address = "http://172.22.0.2:8558"
    }
  }
}
```


| Parameter | Required | Type | Description | Default |
| --------- | -------- | ---- | ----------- | ------- |
| `address` | Optional | string | The address of the Consul agent. It may be an IP or FQDN. | `localhost:8500` |
| `token` | Optional | string | The ACL token to use for client communication with the local Consul agent. Refer to  [ACL Requirements](/consul/docs/automate/infrastructure/configure#acl-requirements) for required privileges. <br/><br/> The token can also be provided through the `CONSUL_TOKEN` or `CONSUL_HTTP_TOKEN` environment variables. | none |
| `auth` | Optional | [auth](/consul/docs/automate/infrastructure/configure#auth) | HTTP basic authentication for communicating with Consul ||
| `tls` | Optional | [tls](/consul/docs/automate/infrastructure/configure#tls-1)  | Secure client connection with Consul ||
| `transport` | Optional | [transport](/consul/docs/automate/infrastructure/configure#transport) | Low-level network connection details ||
| `service_registration` | Optional| [service_registration](/consul/docs/automate/infrastructure/configure#service-registration) | Options for how CTS will register itself as a service with a health check to Consul. ||

### ACL requirements

The following table describes the ACL policies required by CTS. For more information, refer to the [Secure Consul-Terraform-Sync for Production](/consul/tutorials/network-infrastructure-automation/consul-terraform-sync-secure?utm_source=docs#configure-acl-privileges-for-consul-terraform-sync) tutorial.

| Policy | Resources |
| ------ | --------- |
| `service:read` | Any services monitored by tasks |
| `node:read` | Any nodes hosting services monitored by tasks |
| `keys:read` | Any Consul KV pairs monitored by tasks |
| `namespace:read` | <EnterpriseAlert inline />  Any namespaces for resources monitored by tasks |
| `service:write` | The CTS service when [service registration](/consul/docs/automate/infrastructure/configure#service-registration) is enabled |
| `keys:write` | `consul-terraform-sync/` Only required when using Consul as the [Terraform backend](/consul/docs/automate/infrastructure/configure#backend). |


### Auth

Configures HTTP basic authentication for communicating with Consul.

| Parameter | Required | Type | Description | Default |
| --------- | -------- | ---- | ----------- | ------- |
| `enabled` | Optional | boolean | Enables using HTTP basic authentication | `false` |
| `username` | Optional | string | Username for authentication| none |
| `password` | Optional | string | Password for authentication| none |

### TLS

Configure TLS to use a secure client connection with Consul. Using HTTP/2 can solve issues related to hitting Consul's maximum connection limits, as well as improve efficiency when processing many blocking queries. This option is required for Consul-Terraform-Sync when connecting to a [Consul agent with TLS verification enabled for HTTPS connections](/consul/docs/reference/agent/configuration-file/tls#verify_incoming).

If Consul is using a self-signed certificate that you have not added to the global CA chain, you can set this certificate with `ca_cert` or `ca_path`. Alternatively, you can disable SSL verification by setting `verify` to false. However, disabling verification is a potential security vulnerability.

| Parameter | Required | Type | Description | Default |
| --------- | -------- | ---- | ----------- | ------- |
| `enabled` | Optional | boolean | Enable TLS. Providing a value for any of the TLS options enables this parameter implicitly. | `false` |
| `verify` | Optional | boolean | Enables TLS peer verification, which checks the global certificate authority (CA) chain to make sure the certificates returned by Consul are valid. | `true` |
| `ca_cert` | Optional | string | The path to a PEM-encoded certificate authority file used to verify the authenticity of the connection to Consul over TLS.<br/><br/>Can also be provided through the `CONSUL_CACERT` environment variable. | none |
| `ca_path` | Optional | string | The path to a directory of PEM-encoded certificate authority files used to verify the authenticity of the connection to Consul over TLS.<br/><br/>Can also be provided through the `CONSUL_CAPATH` environment variable. | none |
| `cert` | Optional | string | The path to a PEM-encoded client certificate file provided to Consul over TLS in order for Consul to verify the authenticity of the connection from CTS. Required if Consul has `verify_incoming` set to true.<br/><br/>Can also be provided through the `CONSUL_CLIENT_CERT` environment variable. | none |
| `key` | Optional | string | The path to the PEM-encoded private key file used with the client certificate configured by `cert`. Required if Consul has `verify_incoming` set to true.<br/><br/>Can also be provided through the `CONSUL_CLIENT_KEY` environment variable. | none |
| `server_name` | Optional | string | The server name to use as the Server Name Indication (SNI) for Consul when connecting via TLS.<br/><br/>Can also be provided through the `CONSUL_TLS_SERVER_NAME` environment variable. | none |

### Transport

Configures the low-level network connection details to Consul.

To achieve the shortest latency between a Consul service update to a task execution, configure `max_idle_conns_per_host` equal to or greater than the number of services in automation across all tasks. This value should be lower than the configured [`http_max_conns_per_client`](/consul/docs/reference/agent/configuration-file/general#http_max_conns_per_client) for the Consul agent.

If `max_idle_conns_per_host` and the number of services in automation is greater than the Consul agent limit, CTS may error due to connection limits (status code 429). You may increase the agent limit with caution. _Requests to the Consul agent made by Terraform subprocesses or any other process on the same host as CTS will contribute to the Consul agent connection limit._

| Parameter | Required | Type | Description | Default |
| --------- | -------- | ---- | ----------- | ------- |
| `dial_keep_alive` | Optional | string | The amount of time for keep-alives. | `30s` |
| `dial_timeout` | Optional | string | The amount of time to wait to establish a connection. | `30s`
| `disable_keep_alives` | Optional | boolean | Determines if keep-alives should be used. Disabling this significantly decreases performance. | `false`|
| `idle_conn_timeout` | Optional | string | The timeout for idle connections. | `5s` |
| `max_idle_conns` | Optional | integer | The maximum number of total idle connections across all hosts. The limit is disabled by default. | `0` |
| `max_idle_conns_per_host` | Optional | integer | The maximum number of idle connections per remote host. The majority of connections are established with one host, the Consul agent. | `100`|
| `tls_handshake_timeout` | Optional | string | The amount of time to wait to complete the TLS handshake. | `10s`|


### Service registration

CTS automatically registers itself with Consul as a service with a health check, using the [`id`](/consul/docs/automate/infrastructure/configure#id) configuration as the service ID. CTS deregisters itself with Consul when CTS stops gracefully. If CTS is unable to register with Consul, then it will log the error and continue without exiting.

Service registration requires that the [Consul token](/consul/docs/automate/infrastructure/configure#consul) has an ACL policy of `service:write` for the CTS service.

| Parameter | Required | Type | Description | Default |
| --------- | -------- | ---- | ----------- | ------- |
| `enabled` | Optional | boolean | Enables CTS to register itself as a service with Consul. When service registration is enabled for a [CTS instance configured for high availability](/consul/docs/automate/infrastructure/high-availability), the instance also registers itself with a new tag using the `cts-cluster:<cluster-name>` format. | `true` |
| `service_name` | Optional | string | The service name for CTS. We recommended specifying the same name used for [`high_availability.cluster.name`](#high-availability-cluster) value if [CTS is configured for high availability](/consul/docs/automate/infrastructure/high-availability). | `consul-terraform-sync` |
| `address` | Optional | string | The IP address or hostname for CTS. | IP address of the Consul agent node |
| `namespace` | Optional | string |  <EnterpriseAlert inline /> The namespace to register CTS in. | In order of precedence: <br/> 1. Inferred from the CTS ACL token <br/> 2. The `default` namespace. |
| `default_check.enabled` | Optional | boolean | Enables CTS to create the default health check. | `true` |
| `default_check.address` | Optional | string | The address to use for the default HTTP health check. Needs to include the scheme (`http`/`https`) and the port, if applicable. | `http://localhost:<port>` or `https://localhost:<port>`. Determined from the [port configuration](/consul/docs/automate/infrastructure/configure#port) and whether [TLS is enabled](/consul/docs/automate/infrastructure/configure#enabled-2) on the CTS API. |

The default health check is an [HTTP check](/consul/docs/register/health-check/vm#http-checks) that calls the [Health API](/consul/docs/reference/cts/api/health). The following table describes the values CTS sets for this default check, corresponding to the [Consul register check API](/consul/api-docs/agent/check#register-check). If an option is not listed in this table, then CTS is using the default value.

| Parameter | Value |
| --------- | ----- |
| Name | `CTS Health Status`|
| ID | `<id>-health` |
| Namespace | `service_registration.namespace` |
| Notes | `Check created by Consul-Terraform-Sync`|
| DeregisterCriticalServiceAfter | `30m` |
| ServiceID | [`id`](/consul/docs/automate/infrastructure/configure#id) |
| Status | `critical` |
| HTTP | `<default_check.address>/v1/health` |
| Method | `GET` |
| Interval | `10s` |
| Timeout | `2s` |
| TLSSkipVerify | `false` |

## High availability

Add a `high_availability` block to your configuration to enable CTS to run in high availability mode. Refer to [Run Consul-Terraform-Sync with High Availability](/consul/docs/automate/infrastructure/high-availability) for additional information. The `high_availability` block contains the following configuration items.

### High availability cluster

The `cluster` parameter contains configurations for the cluster you want to operate with high availability enabled. You can configure the following options:

| Parameter | Description| Required | Type  |
| --------- | ---------- | -------- | ------|
| `name` | Specifies the name of the cluster operating with high availability enabled. | Required | String |
| `storage` | Configures how CTS stores state information. Refer to [State storage and persistence](/consul/docs/nia/architecture#state-storage-and-persistence) for additional information. You can define storage for the `"consul"` resource. Refer to [High availability cluster storage](#high-availability-cluster-storage) for additional information. | Optional | Object |

#### High availability cluster storage

The `high_availability.cluster.storage` object contains the following configurations.

| Parameter | Description| Required | Type  |
| --------- | ---------- | -------- | ------|
| `parent_path` | Defines a parent path in the Consul KV for CTS to store state information. Default is `consul-terraform-sync/`. CTS automatically appends the cluster name to the parent path, so the effective default directory for state information is `consul-terraform-sync/<cluster-name>`. | Optional | String |
| `namespace` | Specifies the namespace to use when storing state in the Consul KV. Default is inferred from the CTS ACL token. The fallback default is `default`. | Optional | String |
| `session_ttl` | Specifies the session time-to-live for leader elections. You must specify a value greater than the `session_ttl_min` configured for Consul. A longer `session_ttl` results in a longer leader election after a failover. Default is `15s`. | Optional | String |

### High availability instance

The `instance` parameter is an object that contains configurations unique to the CTS instance. You specify the following configurations:
- `address`: (Optional) String value that specifies the IP address of the CTS instance to advertise to other instances. This parameter does not have a default value.


## Service

<Note>

Deprecated in CTS 0.5.0 and will be removed in a future major release. `service` blocks are used to define the `task` block's `services` fields, which were also deprecated and replaced with [Services Condition](/consul/docs/automate/infrastructure/configure#services-condition) and [Services Module Input](/consul/docs/automate/infrastructure/configure#services-module-input). `service` block configuration can be replaced by configuring the equivalent fields of the corresponding Services Condition and Services Module Input. Refer to [0.5.0 release notes](/consul/docs/release-notes/consul-terraform-sync/v0_5_x#deprecate-service-block) for examples.

</Note>

A `service` block is an optional block to explicitly define the services configured in the `task` block's `services` field (deprecated). `service` blocks do not define services configured in the `task` block's `condition "services"` or `module_input "services` blocks.

A `service` block is only necessary for services that have non-default values e.g. custom datacenter. Services that do not have a `service` block configured will assume default values. To configure multiple services, specify multiple `service` blocks. If a `service` block is configured, the service can be referred in `task.services` by service name or ID. If a `service` block is not configured, it can only be referred to by service name.

```hcl
service {
  name        = "web"
  datacenter  = "dc1"
  description = "all instances of the service web in datacenter dc1"
}
```

| Parameter | Required | Type | Description | Default |
| --------- | -------- | ---- | ----------- | ------- |
| `name` |  Required | string | Consul logical name of the service. | none |
| `id` |  Optional | string | Service ID for CTS. This is used to explicitly identify the service config for a task to use. If no ID is provided, the service is identified by the service name within a [task definition](#task). | none |
| `description` |  Optional | string | Human-readable text to describe the service | none |
| `datacenter` |  Optional | string | Name of a datacenter to query for the task. | Datacenter of the agent that CTS queries. |
| `namespace`  | Optional | string |<EnterpriseAlert inline /> <br/> Namespace of the services to query for the task. | In order of precedence: <br/> 1. Inferred from the CTS ACL token <br/> 2. The `default` namespace. |
| `filter` |  Optional | string | Expression used to additionally filter the services to monitor. <br/><br/> Refer to the [services filtering documentation](/consul/api-docs/health#filtering-2) and section about [how to write filter expressions](/consul/api-docs/features/filtering#creating-expressions) for additional information. | none |
| `cts_user_defined_meta` | Optional | map[string] | User-defined metadata that is appended to the [service input variable](/consul/docs/automate/infrastructure/module#services-module-input) for compatible Terraform modules. <br/><br/> Some modules do not use the configured metadata. Refer to the module configured for the task for information about metadata usage and expected keys and format. <br/><br/> If multiple tasks depend on the same service but require different metadata, you can declare different sets of metadata for the same service. Define multiple service blocks for the service with unique IDs (and identical names) for those blocks. The metadata can then be separated per task based on the service IDs. | none|

## Task

A `task` block configures which task to execute in automation. Use  the `condition` block to specify when the task executes. You can specify the `task` block multiple times to configure multiple tasks, or you can omit it entirely. If task blocks are not specified in your initial configuration, you can add them to a running CTS instance by using the [`/tasks` API endpoint](/consul/docs/reference/cts/api/tasks#tasks) or the [CLI's `task` command](/consul/docs/reference/cli/cts/task#task).

```hcl
task {
  name           = "taskA"
  description    = ""
  enabled        = true
  providers      = []
  module         = "org/example/module"
  version        = "1.0.0"
  variable_files = []
  condition "services" {
    names = ["web", "api"]
  }
}
```

- `description` - (string) The human readable text to describe the task.
- `name` - (string: required) Name is the unique name of the task (required). A task name must start with a letter or underscore and may contain only letters, digits, underscores, and dashes.
- `enabled` - (bool: true) Enable or disable a task from running and managing resources.
- `providers` - (list[string]) Providers is the list of provider names the task is dependent on. This is used to map [Terraform provider configuration](#terraform-provider) to the task.
- `services` - (list[string]) **Deprecated in CTS 0.5.0 and will be removed in a future major release. Use [Services Condition](/consul/docs/automate/infrastructure/configure#services-condition) or [Services Module Input](/consul/docs/automate/infrastructure/configure#services-module-input) instead. Refer to  [0.5.0 release notes](/consul/docs/release-notes/consul-terraform-sync/v0_5_x#deprecate-services-field) for examples.** Specifies an optional list of logical service names or service IDs that the task monitors for changes in the Consul catalog. The `services` can act in different ways depending on the configuration of the task's `condition` block:
  - no `condition` block configured: `services` will act as the task's condition and provide the services information as module input
  - the `condition` block configured for type `services`: `services` is incompatible with this type of `condition` because both configure the services module input. CTS will return an error.
  - the `condition` block configured for all other types: `services` will act only to provide services module input.

  Service values that are not explicitly defined by a `service` block that have a matching ID are assumed to be logical service names in the `default` namespace.
- `source` - (string: required) **Deprecated in CTS 0.5.0 and will be removed in a future major release. Refer to  the `module` field instead.**
- `module` - (string: required) Module is the location the driver uses to discover the Terraform module used for automation. The module's source can be local or remote on the [Terraform Registry](https://registry.terraform.io/) or private module registry. Read more on [Terraform module source and other supported types here](/terraform/language/modules/sources).

  - To use a private module with the [`terraform` driver](#terraform-driver), run the command [`terraform login [hostname]`](/terraform/tutorials/cloud/cloud-login?utm_source=docs) to authenticate the local Terraform CLI prior to starting CTS.
  - To use a private module with the [`terraform_cloud` driver](#terraform-cloud-driver), no extra steps are needed.

    ```hcl
    // local module example: "./terraform-cts-hello"
    module = "<PATH>"

    // public module example: "mkam/hello/cts"
    module = "<NAMESPACE>/<MODULE NAME>/<PROVIDER>"

    // private module example: "my.tfe.hostname.io/my-org/hello/cts"
    module = "<HOSTNAME>/<ORGANIZATION>/<MODULE NAME>/<PROVIDER>"
    ```

- `variable_files` - (list[string]) Specifies list of paths to [Terraform variable definition files (`.tfvars`)](/terraform/language/values/variables#variable-definitions-tfvars-files). The content of these files should consist of only variable name assignments. The variable assignments must match the corresponding variable declarations made available by the Terraform module for the task.
  - Variables are loaded in the order they appear in the files. Duplicate variables are overwritten with the later value. _Unless specified by the module, configure arguments for Terraform providers using [`terraform_provider` blocks](#terraform-provider)._

    <CodeBlockConfig filename="example.tfvars">

    ```hcl
    address_group = "consul-services"
    tags = [
      "consul-terraform-sync",
      "terraform"
    ]
    ```

    </CodeBlockConfig>

- `version` - (string) The version of the provided module the task will use. The latest version will be used as the default if omitted.
- `working_dir` - (string) The working directory to manage generated artifacts by CTS for this task, including Terraform configuration files. By default, a working directory is created for each task as a subdirectory in the base [`working_dir`](#working_dir), e.g. `sync-tasks/task-name`.
- `buffer_period` - Configures the buffer period for a dynamic task to dampen the effects of flapping services to downstream network devices. It defines the minimum and maximum amount of time to wait for the cluster to reach a consistent state and accumulate changes before triggering task execution. The default is inherited from the top level [`buffer_period` block](#global-config-options). If configured, these values will take precedence over the global buffer period. This is useful to enable for a task that is dependent on services that have a lot of flapping. Buffer periods do not apply to scheduled tasks.
  - `enabled` - (bool) Enable or disable buffer periods for this task. Specifying `min` will also enable it.
  - `min` - (string: "5s") The minimum period of time to wait after changes are detected before triggering related tasks.
  - `max` - (string: "20s") The maximum period of time to wait after changes are detected before triggering related tasks. If `min` is set, the default period for `max` is 4 times the value of `min`.
- `condition` - (obj: required) The requirement that, when met, triggers CTS to execute the task. Only one `condition` may be configured per task. CTS supports different types of conditions, which each have their own configuration options. Refer to  [Task Condition](#task-condition) configuration for full details on configuration options for each condition type.
- `source_input` - (obj) **Deprecated in CTS 0.5.0 and will be removed in 0.8.0. Refer to  the `module_input` block instead.**
- `module_input` - (obj) Specifies a Consul object containing values or metadata to be provided to the Terraform Module. The `module_input` block defines any extra module inputs needed for task execution.  This is in addition to any module input provided by the `condition` block or `services` field (deprecated). Multiple `module_input` blocks can be configured per task. [Task Module Input](#task-module-input) configuration for full details on usage and restrictions.
- `terraform_version` - (string) <EnterpriseAlert inline />  **Deprecated in CTS 0.6.0 and will be removed in 0.8.0. Review `terraform_cloud_workspace.terraform_version` instead.** The version of Terraform to use for the Terraform Cloud workspace associated with the task. Defaults to the latest compatible version supported by the organization. This option is only available when used with the [Terraform Cloud driver](#terraform-cloud-driver); otherwise, set the version within the [Terraform driver](#terraform-driver).
- `terraform_cloud_workspace` - (obj) <EnterpriseAlert inline /> Configures attributes of the Terraform Cloud workspace associated with the task. This option is only available when used with the [Terraform Cloud driver](#terraform-cloud-driver). For global configurations of all workspaces, review [`driver.workspaces`](#workspaces).
  - `execution_mode` - (string: "remote") The execution mode that determines whether to use Terraform Cloud as the Terraform execution platform. Only supports "remote" or "agent".
  - `agent_pool_id` - (string) Only supported if `execution_mode` is set to "agent". The ID of the agent pool that should run the Terraform workloads. Either `agent_pool_id` or `agent_pool_name` are required if `execution_mode` is set to "agent". `agent_pool_id` takes precedence over `agent_pool_name` if both are provided.
  - `agent_pool_name` - (string) Only supported if `execution_mode` is set to "agent". The name of the agent pool that should run the Terraform workloads. Only supported if `execution_mode` is set to "agent". Either `agent_pool_id` or `agent_pool_name` are required. `agent_pool_id` takes precedence over `agent_pool_name` if both are provided.
  - `terraform_version` - (string) The version of Terraform to use for the Terraform Cloud workspace associated with the task. Defaults to the latest compatible version supported by the organization.

### Task condition

A `task` block is configured with a `condition` block to set the conditions that should be met in order to execute that particular task. Below are the different types of conditions that CTS supports.

#### Services condition

This condition will trigger the task on services that match the regular expression configured in `regexp` or services listed by name in `names`. Either `regexp` or `names` must be configured, but not both.

When a `condition "services"` block is configured for a task, then the following restrictions become applicable:
- the task cannot be configured with the `services` field (deprecated)
- the task cannot be configure with a `module_input "services"` or `source_input "services"` (deprecated) block

CTS places these restrictions because the monitored services information for a task can only be set through one configuration option. Any services module input that the task needs should be configured solely through the `condition` block.

Refer to [Task Execution: Services Condition](/consul/docs/reference/cts/api/tasks#services-condition) for more details on how tasks are triggered with a services condition.

```hcl
task {
  name        = "services_condition_regexp_task"
  description = "execute on changes to services with names starting with web"
  providers   = ["my-provider"]
  module      = "path/to/services-condition-module"

  condition "services" {
    regexp     = "^web.*"
    datacenter = "dc1"
    namespace  = "default"
    filter     = "Service.Tags not contains \"prod\""
    cts_user_defined_meta {
      key = "value"
    }
  }
}
```

```hcl
task {
  name        = "services_condition_names_task"
  description = "execute on changes to services with names api or web"
  module      = "path/to/services-condition-module"

  condition "services" {
    names = ["api", "web"]
    datacenter = "dc1"
    namespace  = "default"
    filter     = "Service.Tags not contains \"prod\""
    cts_user_defined_meta {
      key = "value"
    }
  }
}

```

| Parameter | Required | Type | Description | Default |
| --------- | -------- | ---- | ----------- | ------- |
| `regexp` |  Required if `names` is not configured | string | Regular expression used to match the names of Consul services to monitor. Only services that have a name matching the regular expression are used by the task. <br/><br/> If both a list and a regex are needed, consider including the list as part of the regex or creating separate tasks. | none |
| `names` |  Required if `regexp` is not configured | list[string] | Names of Consul services to monitor. Only services that have their name listed in `names` are used by the task. | none |
| `datacenter` |  Optional | string | Name of a datacenter to query for the task. | Datacenter of the agent that CTS queries. |
| `namespace`  | Optional | string | <EnterpriseAlert inline /> <br/> Namespace of the services to query for the task. | In order of precedence: <br/> 1. Inferred from the CTS ACL token <br/> 2. The `default` namespace. |
| `filter` |  Optional | string | Expression used to additionally filter the services to monitor. <br/><br/> Refer to the [services filtering documentation](/consul/api-docs/health#filtering-2) and section about [how to write filter expressions](/consul/api-docs/features/filtering#creating-expressions) for additional information. | none |
| `cts_user_defined_meta` | Optional | map[string] | User-defined metadata that is appended to the [service input variable](/consul/docs/automate/infrastructure/module#services-module-input) for compatible Terraform modules. <br/><br/> Some modules do not use the configured metadata. Refer to the module configured for the task for information about metadata usage and expected keys and format. | none|
| `source_includes_var` | Optional | boolean | **Deprecated in CTS 0.5.0 and will be removed in 0.8.0. Refer to  the `use_as_module_input` field instead.** | true |
| `use_as_module_input` | Optional | boolean | Whether or not the values of the condition object should also be used as input for the [`services` variable](/consul/docs/automate/infrastructure/module#services-variable) for the Terraform module<br/><br/> Please refer to the selected module's documentation for guidance on how to configure this field. If configured inconsistently with the module, CTS will error and exit. | true |


#### Catalog-services condition

A catalog-services condition block configures a task to only execute on service registration and deregistration, more specifically on first service instance registration and last service instance deregistration respectively. The catalog-services condition has additional configuration options to specify the services that can trigger the task on registration and deregistration.

Refer to [Task Execution: Catalog Services Condition](/consul/docs/reference/cts/api/tasks#catalog-services-condition) for more information on how tasks are triggered with a catalog-services condition.

```hcl
task {
  name        = "catalog_service_condition_task"
  description = "execute on service de/registrations with name matching 'web.*'"
  module      = "path/to/catalog-services-module"
  providers   = ["my-provider"]

  condition "catalog-services" {
    datacenter          = "dc1"
    namespace           = "default"
    regexp              = "web.*"
    use_as_module_input = true
    node_meta {
      key = "value"
    }
  }
}
```

| Parameter | Required | Type | Description | Default |
| --------- | -------- | ---- | ----------- | ------- |
| `regexp` |  Required | string | Regular expression used to match the names of Consul service to monitor for registration and deregistration. Only services that have a name matching the regular expression are used by the task. <br/><br/> Refer to [regular expression syntax documentation](https://github.com/google/re2/wiki/Syntax) and [try out regular expression string matching](https://golang.org/pkg/regexp/#Regexp.MatchString) for additional information. | none |
| `datacenter` | Optional | string | Name of a datacenter to query for the task. | Datacenter of the agent that CTS queries. |
| `namespace`  | Optional | string | <EnterpriseAlert inline /> <br/> Namespace of the services to query for the task. | In order of precedence: <br/> 1. Inferred from the CTS ACL token <br/> 2. The `default` namespace. |
| `node_meta`  | Optional | map[string] | Node metadata key/value pairs to use to filter services. Only services registered at a node with the specified key/value pairs are used by the task.  | none |
| `source_includes_var` | Optional | boolean | **Deprecated in CTS 0.5.0 and will be removed in 0.8.0. Refer to  the `use_as_module_input` field instead.** | true |
| `use_as_module_input` | Optional | boolean | Whether or not the values of the condition object should also be used as input for the [`catalog_services` variable](/consul/docs/automate/infrastructure/module#catalog-services-variable) for the Terraform module<br/><br/> Please refer to the selected module's documentation for guidance on how to configure this field. If configured inconsistently with the module, CTS will error and exit. | true |

#### Consul KV condition

A `condition "consul-kv"` block configures a task to only execute on changes to a Consul KV entry. The condition can be configured for a single Consul KV entry or for any Consul KV entries that are prefixed with a given path.

When a `condition "consul-kv"` block is configured for a task, the task cannot be configured with a `module_input "consul-kv"` or `source_input "consul-kv"` (deprecated) block. The monitored consul-kv information for a task can only be set through one configuration option. Any consul-kv module input that the task needs should be configured solely through the `condition` block.

Refer to [Task Execution: Consul KV Condition](/consul/docs/reference/cts/api/tasks#consul-kv-condition) for more information on how tasks are triggered with a consul-kv condition.

```hcl
task {
  name        = "consul_kv_condition_task"
  description = "execute on changes to Consul KV entry"
  module      = "path/to/consul-kv-module"
  providers   = ["my-provider"]

  condition "consul-kv" {
    path                = "my-key"
    recurse             = false
    datacenter          = "dc1"
    namespace           = "default"
    use_as_module_input = true
  }
}
```

| Parameter | Required | Type | Description | Default |
| --------- | -------- | ---- | ----------- | ------- |
| `path` |  Required | string | Path of the key used by the task. The path can point to a single Consul KV entry or several entries within the path. | none |
| `recurse` |  Optional | boolean | Enables CTS to treat the path as a prefix. If set to `false`, the path will be treated as a literal match. | `false` |
| `datacenter` |  Optional | string | Name of a datacenter to query for the task. | Datacenter of the agent that CTS queries. |
| `namespace`  | Optional | string | <EnterpriseAlert inline /> <br/> Namespace of the services to query for the task. | In order of precedence: <br/> 1. Inferred from the CTS ACL token <br/> 2. The `default` namespace. |
| `source_includes_var` | Optional | boolean | **Deprecated in CTS 0.5.0 and will be removed in 0.8.0. Refer to  the `use_as_module_input` field instead.** | true |
| `use_as_module_input` | Optional | boolean | Whether or not the values of the condition object should also be used as input for the [`consul_kv` variable](/consul/docs/automate/infrastructure/module#consul-kv-variable) for the Terraform module<br/><br/> Please refer to the selected module's documentation for guidance on how to configure this field. If configured inconsistently with the module, CTS will error and exit. | true |


#### Schedule condition

A scheduled task has a schedule condition block, which defines the schedule for executing the task. Unlike a dynamic task, a scheduled task does not dynamically trigger on changes in Consul.

Schedule tasks also rely on additional task configuration, separate from the condition block to determine the module input information to provide to the task module. Refer to  [`module_input`](#module_input) block configuration for details on how to configure module input.

Refer to [Task Execution: Schedule Condition](/consul/docs/reference/cts/api/tasks#schedule-condition) for more information on how tasks are triggered with schedule conditions.

Refer to [Terraform Module: Module Input](/consul/docs/automate/infrastructure/module#module-input) for more information on module input options for a scheduled task.

```hcl
task {
  name        = "scheduled_task"
  description = "execute every Monday using service information from web and db"
  module      = "path/to/module"

  condition "schedule" {
    cron = "* * * * Mon"
  }

  module_input "services" {
    names = ["web", "db"]
  }
}
```

| Parameter | Required | Type | Description | Default |
| --------- | -------- | ---- | ----------- | ------- |
| `cron` |  Required | string | The CRON expression that dictates the schedule to trigger the task. For more information on CRON expressions, refer to  the [cronexpr parsing library](https://github.com/hashicorp/cronexpr). | none |

### Task Module Input ((#task-source-input))

<Note>

`module_input` was renamed from `source_input` in CTS 0.5.0. Documentation for the `module_input` block also applies to the `source_input` block.

</Note>

You can optionally add one or more `module_input` blocks to the `task` block. A `module_input` block specifies a Consul object containing values or metadata to be provided to the Terraform Module. Both scheduled and dynamic tasks can be configured with `module_input` blocks.

The example below shows an outline of `module_input` within a task configuration:

```hcl
task {
  name     = "task_a"
  module   = "path/to/module"
  services = ["api"] // (deprecated)

  condition "<condition-type>" {
    // ...
  }

  module_input "<input-type>" {
    // ...
  }
}
```

The type of the `module_input` block that can be configured depends on the `condition` block type and the `services` field (deprecated). Refer to [Task Module Input Restrictions](/consul/docs/automate/infrastructure/configure#task-module-input-restrictions) for more details.

The following sections describe the module input types that CTS supports.

#### Services module input ((#services-source-input))

This `services` module input object defines services registered to Consul whose metadata will be used as [services module input to the Terraform Module](/consul/docs/automate/infrastructure/module/#services-module-input). The following parameters are supported:

| Parameter | Required | Type | Description | Default |
| --------- | -------- | ---- | ----------- | ------- |
| `regexp` |  Required if `names` is not configured | string | Regular expression used to match the names of Consul services to monitor. Only services that have a name matching the regular expression are used by the task. <br/><br/> If both a list and a regex are needed, consider including the list as part of the regex or creating separate tasks. | none |
| `names` |  Required if `regexp` is not configured | list[string] | Names of Consul services to monitor. Only services that have their name listed in `names` are used by the task. | none |
| `datacenter` |  Optional | string | Name of a datacenter to query for the task. | Datacenter of the agent that CTS queries. |
| `namespace` | Optional | string |<EnterpriseAlert inline /> <br/> String value indicating the namespace of the services to query for the task. | In order of precedence: <br/> 1. Inferred from the CTS ACL token <br/> 2. The `default` namespace. |
| `filter` |  Optional | string | Expression used to additionally filter the services to monitor. <br/><br/> Refer to the [services filtering documentation](/consul/api-docs/health#filtering-2) and section about [how to write filter expressions](/consul/api-docs/features/filtering#creating-expressions) for additional information. | none |
| `cts_user_defined_meta` | Optional | map[string] | User-defined metadata that is appended to the [service input variable](/consul/docs/automate/infrastructure/module#services-module-input) for compatible Terraform modules. <br/><br/> Some modules do not use the configured metadata. Refer to the module configured for the task for information about metadata usage and expected keys and format. | none|

In the following example, the scheduled task queries all Consul services with `web` as the suffix. The metadata of matching services are provided to the Terraform module.

```hcl
task {
  name        = "schedule_condition_task"
  description = "execute every Monday using information from service names starting with web"
  module      = "path/to/module"

  condition "schedule" {
    cron = "* * * * Mon"
  }

  module_input "services" {
    regexp = "^web.*"
    datacenter = "dc1"
    namespace  = "default"
    filter     = "Service.Tags not contains \"prod\""
    cts_user_defined_meta {
      key = "value"
    }
  }
}
```

#### Consul KV module input ((#consul-kv-source-input))

A Consul KV module input block defines changes to Consul KV that will be monitored. These changes will then be provided as [Consul KV module input to the Terraform Module](/consul/docs/automate/infrastructure/module/#consul-kv-module-input). The module input can be configured for a single Consul KV entry or for any Consul KV entries that are prefixed with a given path. The following parameters are supported:

| Parameter | Required | Type | Description | Default |
| --------- | -------- | ---- | ----------- | ------- |
| `path` |  Required | string | Path of the key used by the task. The path can point to a single Consul KV entry or several entries within the path. | none |
| `recurse` |  Optional | boolean | Enables CTS to treat the path as a prefix. If set to `false`, the path will be treated as a literal match. | `false` |
| `datacenter` |  Optional | string | Name of a datacenter to query for the task. | Datacenter of the agent that CTS queries. |
| `namespace`  | Optional | string | <EnterpriseAlert inline /> <br/> Namespace of the services to query for the task. | In order of precedence: <br/> 1. Inferred from the CTS ACL token <br/> 2. The `default` namespace. |

In the following example, the scheduled task queries datacenter `dc1` in the `default` namespace for changes to the value held by the key `my-key`.

```hcl
task {
  name        = "schedule_condition_task_kv"
  description = "execute every Monday using information from Consul KV entry my-key"
  module      =  "path/to/module"

  condition "schedule" {
    cron = "* * * * Mon"
  }

  module_input "consul-kv" {
    path       = "my-key"
    recurse    = false
    datacenter = "dc1"
    namespace  = "default"
  }
}
```

#### Task module input restrictions

There are some limitations to the type of `module_input` blocks that can be configured for a task given the task's `condition` block and `services` field (deprecated). This is because a task cannot have multiple configurations defining the same type of monitored variable:
- A task cannot be configured with a `condition` and `module_input` block of the same type. For example, configuring `condition "consul-kv"` and `module_input "consul-kv"` will error because both configure the `consul_kv` variable.
- A task cannot be configured with two or more `module_input` blocks of the same type. For example, configuring two `module_input "catalog-services"` within a task will return an error because they define multiple configurations for the `catalog_services` variable.
- A task that monitors services can only contain one of the following configurations:
  - `condition "services"` block
  - `module_input "services"` block
    - Block was previously named `source_input "services"` (deprecated)
  - `services` field (deprecated)

  All of the listed configurations define the `services` variable and including more than one configuration will return an error.

## Network drivers

A driver is required for CTS to propagate network infrastructure change. The `driver` block configures the subprocess that CTS runs in automation. The default driver is the [Terraform driver](#terraform-driver) which automates Terraform as a local installation of the Terraform CLI.

Only one network driver can be configured per deployment of CTS.

## Terraform driver

The Terraform driver block is used to configure CTS for installing and automating Terraform locally. The driver block supports Terraform configuration to specify the `backend` used for state management and `required_providers` configuration used for provider discovery.

```hcl
driver "terraform" {
  log         = false
  persist_log = false
  path        = ""

  backend "consul" {
    gzip = true
  }

  required_providers {
    myprovider = {
      source  = "namespace/myprovider"
      version = "1.3.0"
    }
  }
}
```

- `backend` - (obj) The backend stores [Terraform state files](/terraform/language/state) for each task. This option is similar to the [Terraform backend configuration](/terraform/language/settings/backends/configuration). CTS supports Terraform backends used as a state store.
  - Supported backend options: [azurerm](/terraform/language/settings/backends/azurerm), [consul](/terraform/language/settings/backends/consul), [cos](/terraform/language/settings/backends/cos), [gcs](/terraform/language/settings/backends/gcs), [kubernetes](/terraform/language/settings/backends/kubernetes), [local](/terraform/language/settings/backends/local), [manta](/terraform/language/v1.2.x/settings/backends/manta), [pg](/terraform/language/settings/backends/pg) (Terraform v0.14+), [s3](/terraform/language/settings/backends/s3). Visit the Terraform documentation links for details on backend configuration options.
  - If omitted, CTS will generate default values and use configurations from the [`consul` block](#consul) to configure [Consul as the backend](/terraform/language/settings/backends/consul), which stores Terraform statefiles in the Consul KV. The [ACL token provided for Consul authentication](#consul) is used to read and write to the KV store and requires [Consul KV privileges](/consul/tutorials/network-infrastructure-automation/consul-terraform-sync-secure?utm_source=docs#configure-acl-privileges-for-consul-terraform-sync). The Consul KV path is the base path to store state files for tasks. The full path of each state file will have the task identifier appended to the end of the path, e.g. `consul-terraform-sync/terraform-env:task-name`.
  - The remote enhanced backend is not supported with the Terraform driver to run operations in Terraform Cloud. Use the [Terraform Cloud driver](#terraform-cloud-driver) to integrate CTS with Terraform Cloud for remote workspaces and remote operations.
  - The `local` backend type is not supported with CTS instances configured for high availability. If high availability is configured and the Terraform backend type is `local`, CTS logs an error and exits.
- `log` - (bool) Enable all Terraform output (stderr and stdout) to be included in the CTS log. This is useful for debugging and development purposes. It may be difficult to work with log aggregators that expect uniform log format.
- `path` - (string) The file path to install Terraform or discover an existing Terraform binary. If omitted, Terraform will be installed in the same directory as the CTS daemon. To resolve an incompatible Terraform version or to change versions will require removing the existing binary or change to a different path.
- `persist_log` - (bool) Enable trace logging for each Terraform client to disk per task. This is equivalent to setting `TF_LOG_PATH=<work_dir>/terraform.log`. Trace log level results in verbose logging and may be useful for debugging and development purposes. We do not recommend enabling this for production. There is no log rotation and may quickly result in large files.
- `required_providers` - (obj: required) Declare each Terraform provider used across all tasks. This can be configured the same as how you would configure [Terraform `terraform.required_providers`](/terraform/language/providers/requirements#requiring-providers) field to specify the source and version for each provider. CTS will process these requirements when preparing each task that uses the provider.
- `version` - (string) The Terraform version to install and run in automation for task execution. If omitted, the driver will install the latest [compatible release of Terraform](/consul/docs/nia/compatibility#terraform). To change versions, remove the existing binary or change the path to install the desired version. Verify that the desired Terraform version is compatible across all Terraform modules used for CTS automation.

## Terraform Cloud driver

<EnterpriseAlert>
  This feature requires{' '}
  <a href="https://www.hashicorp.com/products/consul/features">
    Consul-Terraform-Sync Enterprise
  </a>{' '}
  which is available with <strong>Consul Enterprise</strong>.
</EnterpriseAlert>

The Terraform Cloud driver enables CTS Enterprise to integrate with **Terraform Cloud**, including both the [self-hosted distribution](https://www.hashicorp.com/products/terraform/editions/enterprise) and the [managed service](https://www.hashicorp.com/products/terraform/editions/cloud). With this driver, CTS automates Terraform runs and remote operations for workspaces.

An overview of features enabled with Terraform Cloud can be viewed within the [Network Drivers](/consul/docs/automate/infrastructure/network-driver) documentation.

Only one network driver can be configured per deployment of CTS.

```hcl
driver "terraform-cloud" {
  hostname     = "https://app.terraform.io"
  organization = "my-org"
  token        = "<TEAM_TOKEN>"
  // Optionally set the token to be securely queried from Vault instead of
  // written directly to the configuration file.
  // token = "{{ with secret \"secret/my/path\" }}{{ .Data.data.foo }}{{ end }}"

  workspaces {
    tags           = ["source:cts"]
    tags_allowlist = []
    tags_denylist  = []
  }

  required_providers {
    myprovider = {
      source  = "namespace/myprovider"
      version = "1.3.0"
    }
  }
}
```

- `hostname` - (string) The Terraform Cloud hostname to connect to. Can be overridden with the `TFC_HOSTNAME` environment variable.
- `organization` - (string) The Terraform Cloud organization that hosts the managed workspaces by CTS. Can be overridden with the `TFC_ORGANIZATION` environment variable.
- `token` - (string) Required [Team API token](/terraform/cloud-docs/users-teams-organizations/api-tokens#team-api-tokens) used for authentication with Terraform Cloud and workspace management. Only workspace permissions are needed for CTS. The token can also be provided using the `TFC_TOKEN` environment variable.
  - We recommend creating a dedicated team and team API token to isolate automation by CTS from other Terraform Cloud operations.
- `workspace_prefix` - (string) **Deprecated in CTS 0.5.0**, use the [`workspaces.prefix`](#prefix) option instead. Specifies a prefix to prepend to the automatically-generated workspace names used for automation. This prefix will be used by all tasks that use this driver. By default, when no prefix is configured, the workspace name will be the task name. When a prefix is configured, the workspace name will be `<workspace_prefix value>-<task name>`, with the character '-' between the workspace prefix and task name. For example, if you configure the prefix as "cts", then a task with the name "task-firewall" will have the workspace name "cts-task-firewall".
- `workspaces` - Configure CTS management of Terraform Cloud workspaces.
  - `prefix` - (string) Specifies a prefix to prepend to the workspace names used for CTS task automation. This prefix will be used by all tasks that use this driver. By default, when no prefix is configured, the workspace name will be the task name. When a prefix is configured, the workspace name will be `<prefix><task name>`. For example, if you configure the prefix as "cts_", then a task with the name "task_firewall" will have the workspace name "cts_task_firewall".
  - `tags` - (list[string]) Tags for CTS to add to all automated workspaces when the workspace is first created or discovered. Tags are added to discovered workspaces only if the workspace meets [automation requirements](/consul/docs/nia/network-drivers/terraform-cloud#remote-workspaces) and satisfies the allowlist and denylist tag options. This option will not affect existing tags. Tags that were manually removed during runtime will be re-tagged when CTS restarts. Compatible with Terraform Cloud and Terraform Enterprise v202108-1+
  - `tags_allowlist` - (list[string]) Tag requirement to use as a provision check for CTS automation of workspaces. When configured, Terraform Cloud workspaces must have at least one tag from the allow list for CTS to automate the workspace and runs. Compatible with Terraform Cloud and Terraform Enterprise v202108-1+.
  - `tags_denylist` - (list[string]) Tag restriction to use as a provision check for CTS automation of workspaces. When configured, Terraform Cloud workspaces must not have any tag from the deny list for CTS to automate the workspace and runs. Denied tags have higher priority than tags set in the `tags_allowlist` option. Compatible with Terraform Cloud and Terraform Enterprise v202108-1+.
- `required_providers` - (obj: required) Declare each Terraform provider used across all tasks. This can be configured the same as how you would configure [Terraform `terraform.required_providers`](/terraform/language/providers/requirements#requiring-providers) field to specify the source and version for each provider. CTS will process these requirements when preparing each task that uses the provider.
- `tls` - Configure TLS to allow HTTPS connections to [Terraform Enterprise](/terraform/enterprise/install/interactive/installer#tls-key-amp-cert).
  - `enabled` - (bool) Enable TLS. Providing a value for any of the TLS options will enable this parameter implicitly.
  - `ca_cert` - (string) The path to a PEM-encoded certificate authority file used to verify the authenticity of the connection to Terraform Enterprise over TLS.
  - `ca_path` - (string) The path to a directory of PEM-encoded certificate authority files used to verify the authenticity of the connection to Terraform Enterprise over TLS.
  - `cert` - (string) The path to a PEM-encoded client certificate file provided to Terraform Enterprise over TLS in order for Terraform Enterprise to verify the authenticity of the connection from CTS.
  - `key` - (string) The path to the PEM-encoded private key file used with the client certificate configured by `cert` for communicating with Terraform Enterprise over TLS.
  - `server_name` - (string) The server name to use as the Server Name Indication (SNI) for Terraform Enterprise when connecting via TLS.
  - `verify` - (bool: true) Enables TLS peer verification. The default is enabled, which will check the global certificate authority (CA) chain to make sure the certificates returned by Terraform Enterprise are valid.
    - If Terraform Enterprise is using a self-signed certificate that you have not added to the global CA chain, you can set this certificate with `ca_cert` or `ca_path`. Alternatively, you can disable SSL verification by setting `verify` to false. However, disabling verification is a potential security vulnerability.
      ```hcl
      tls {
        verify = false
      }
      ```

CTS generates local artifacts to prepare configuration versions used for workspace runs. The location of the files created can be set with the [`working_dir`](/consul/docs/automate/infrastructure/configure#working_dir) option or configured per task. When a task is configured with a local module and is run with the Terraform Cloud driver, the local module is copied and uploaded as a part of the configuration version.

The version of Terraform to use for each workspace can also be set within the [task](#task) configuration.

## Terraform provider

A `terraform_provider` block configures the options to interface with network infrastructure. Define a block for each provider required by the set of Terraform modules across all tasks. This block resembles [provider blocks for Terraform configuration](/terraform/language/providers/configuration). To find details on how to configure a provider, refer to the corresponding documentation for the Terraform provider. The main directory of publicly available providers are hosted on the [Terraform Registry](https://registry.terraform.io/browse/providers).

The below configuration captures the general design of defining a provider using the [AWS Terraform provider](https://registry.terraform.io/providers/hashicorp/aws/latest/docs) as an example.

```hcl
driver "terraform" {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "3.33.0"
    }
  }
}

terraform_provider "aws" {
  // Configuration options
  region = "us-east-1"
}

task {
  module    = "path/to/module"
  providers = ["aws"]
  condition "services" {
    names = ["web", "api"]
  }
}
```

<Note>

Provider arguments configured in CTS configuration files are written in plain text to the generated [`terraform.tfvars`](/consul/docs/nia/network-drivers#terraform-tfvars) file for each Terraform workspace that references the provider. To exclude arguments or dynamic values from rendering to local files in plain text, use [`task_env` in addition to using dynamic configuration](#securely-configure-terraform-providers).

</Note>

### Securely configure Terraform providers

The `terraform_provider` block supports dynamically loading arguments and the local environment from other sources. This can be used to securely configure your Terraform provider from the shell environment, Consul KV, or Vault. Using the `task_env` meta-argument and template syntax below, you can avoid exposing sensitive values or credentials in plain text within configuration files for CTS.

`task_env` and the template syntax for dynamic values are only supported within the `terraform_provider` block.

#### Provider environment variables

Terraform providers may support shell environment variables as values for some of their arguments. When available, we recommend using environment variables as a way to keep credentials out of plain-text configuration files. Refer to the official provider docs hosted on the [Terraform Registry](https://registry.terraform.io/browse/providers) to find supported environment variables for a provider. By default, CTS enables all Terraform workspaces to inherit from its environment.

The `task_env` block is a meta-argument available for the `terraform_provider` block that can be used to rename or scope the available environment to a selected set of variables. Passing sensitive values as environment variables will scope the values to only the tasks that require the provider.

```hcl
terraform_provider "foo" {
  // Direct assignment of provider arguments are rendered in plain-text within
  // the CTS configuration and the generated terraform.tfvars
  // file for the corresponding Terraform workspaces.
  // token = "<token value>"

  // Instead of configuring the token argument directly for the provider,
  // use the provider's supported environment variable for the token argument.
  // For example,
  // $ export FOO_TOKEN = "<token value>"

  // Dynamically assign the task's environment from the shell env, Consul KV,
  // Vault.
  task_env {
    "FOO_TOKEN" = "{{ env \"CTS_FOO_TOKEN\" }}"
  }
}
```

<Warning title="Security warning">

CTS does not prevent sensitive values from being written to Terraform state files. We recommend securing state files in addition to securely configuring Terraform providers. Options for securing state files can be set within [`driver.backend`](#backend) based on the backend used. For example, Consul KV is the default backend and can be secured with ACLs for KV path. For other backends, we recommend enabling encryption, if applicable.

</Warning>

#### Load dynamic values

Load dynamic values for Terraform providers with integrated template syntax.

##### Env

`env` reads the given environment variable accessible to CTS.

```hcl
terraform_provider "example" {
  address = "{{ env \"EXAMPLE_HOSTNAME\" }}"
}
```

#### Consul

`key` queries the key's value in the KV store of the Consul server configured in the required [`consul` block](#consul).

```hcl
terraform_provider "example" {
  value = "{{ key \"path/example/key\" }}"
}
```

#### Vault

`with secret` queries the [Vault KV secrets engine](/vault/api-docs/secret/kv). Vault is an optional source that require operators to configure the Vault client with a [`vault` block](#vault-configuration). Access the secret using template dot notation `Data.data.<secret_key>`.

```hcl
vault {
  address = "vault.example.com"
}

terraform_provider "example" {
  token = "{{ with secret \"secret/my/path\" }}{{ .Data.data.foo }}{{ end }}"
}
```

##### Vault configuration

- `address` - (string) The URI of the Vault server. This can also be set via the `VAULT_ADDR` environment variable.
- `enabled` - (bool) Enabled controls whether the Vault integration is active.
- `namespace` - (string) Namespace is the Vault namespace to use for reading secrets. This can also be set via the `VAULT_NAMESPACE` environment variable.
- `renew_token` - (bool) Renews the Vault token. This can also be set via the `VAULT_RENEW_TOKEN` environment variable.
- `tls` - [(tls block)](#tls-1) TLS indicates the client should use a secure connection while talking to Vault. Supports the environment variables:
  - `VAULT_CACERT`
  - `VAULT_CAPATH`
  - `VAULT_CLIENT_CERT`
  - `VAULT_CLIENT_KEY`
  - `VAULT_SKIP_VERIFY`
  - `VAULT_TLS_SERVER_NAME`
- `token` - (string) Token is the Vault token to communicate with for requests. It may be a wrapped token or a real token. This can also be set via the `VAULT_TOKEN` environment variable, or via the `VaultAgentTokenFile`.
- `vault_agent_token_file` - (string) The path of the file that contains a Vault Agent token. If this is specified, CTS will not try to renew the Vault token.
- `transport` - [(transport block)](#transport) Transport configures the low-level network connection details.
- `unwrap_token` - (bool) Unwraps the provided Vault token as a wrapped token.

<Note>

  Vault credentials are not accessible by tasks and the associated Terraform configurations, including automated Terraform modules. If the task requires Vault, you will need to separately configure the Vault provider and explicitly include it in the `task.providers` list.

</Note>

### Multiple provider configurations

CTS supports the [Terraform feature to define multiple configurations](/terraform/language/providers/configuration#alias-multiple-provider-configurations) for the same provider by utilizing the `alias` meta-argument. Define multiple provider blocks with the same provider name and set the `alias` to a unique value across a given provider. Select which provider configuration to use for a task by specifying the configuration with the provider name and alias (`<name>.<alias>`) within the list of providers in the [`task.provider`](#task) parameter. A task can use multiple providers, but only one provider instance of a provider is allowed per task.

The example CTS configuration below defines two similar tasks executing the same module with different instances of the AWS provider.

```hcl
terraform_provider "aws" {
  alias   = "a"
  profile = "team-a"
  task_env {
    "AWS_ACCESS_KEY_ID" = "{{ env \"CTS_AWS_ACCESS_KEY_ID_A\" }}"
  }
}

terraform_provider "aws" {
  alias   = "b"
  profile = "team-b"
  task_env {
    "AWS_ACCESS_KEY_ID" = "{{ env \"CTS_AWS_ACCESS_KEY_ID_B\" }}"
  }
}

terraform_provider "dns" {
  // ...
}

task {
  name      = "task-a"
  module    = "org/module"
  providers = ["aws.a", "dns"]
  // ...
}

task {
  name      = "task-b"
  module    = "org/module"
  providers = ["aws.b", "dns"]
  // ...
}
```
