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 to learn the HCL syntax.
Global configurations
Top level options are reserved for configuring CTS.
log_level = "INFO"working_dir = "sync-tasks"port = 8558id = "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 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. Specifyingmin
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. Ifmin
is set, the default period formax
is 4 times the value ofmin
.
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 formatcts-<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.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 thetask.working_dir
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 bycert
.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 theca_cert
orca_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 whenverify_incoming
is set to true. Takes precedence overca_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 whenverify_incoming
is set to true.
license_path
Enterprise - (string) Deprecated in CTS 0.6.0 and will be removed in a future release. Use license block 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 theCONSUL_LICENSE
andCONSUL_LICENSE_PATH
environment variables. For more information, refer to Setting the License.
License Enterprise
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.
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. | none |
auto_retrieval | Optional | object | Configures the license auto-retrieval used by CTS. To learn more, review Auto-Retrieval for details | Review Auto-Retrieval for defaults. |
Auto-retrieval
You can use the auto_retrieval
block to configure the 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.
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.
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 must be configured for the local Consul with the cert_file and 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
.
To read more on suggestions for configuring the Consul agent, see run an agent.
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. See ACL Requirements for required privileges. The token can also be provided through the CONSUL_TOKEN or CONSUL_HTTP_TOKEN environment variables. | none |
auth | Optional | auth | HTTP basic authentication for communicating with Consul | |
tls | Optional | tls | Secure client connection with Consul | |
transport | Optional | transport | Low-level network connection details | |
service_registration | Optional | 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 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 | Enterprise Any namespaces for resources monitored by tasks |
service:write | The CTS service when service registration is enabled |
keys:write | consul-terraform-sync/ Only required when using Consul as the Terraform 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.
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. 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. 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.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.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. 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
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. Note: 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
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 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, 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 value if CTS is configured for 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 | Enterprise The namespace to register CTS in. | In order of precedence: 1. Inferred from the CTS ACL token 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 and whether TLS is enabled on the CTS API. |
The default health check is an HTTP check that calls the Health API. The following table describes the values CTS sets for this default check, corresponding to the Consul register check API. 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 |
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 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 for additional information. You can define storage for the "consul" resource. Refer to 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 and 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 for examples.
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.
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. | 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 | Enterprise Namespace of the services to query for the task. | In order of precedence: 1. Inferred from the CTS ACL token 2. The default namespace. |
filter | Optional | string | Expression used to additionally filter the services to monitor. Refer to the services filtering documentation and section about how to write filter expressions for additional information. | none |
cts_user_defined_meta | Optional | map[string] | User-defined metadata that is appended to the service input variable for compatible Terraform modules. 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. 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 or the CLI's task
command.
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 to the task.services
- (list[string]) Deprecated in CTS 0.5.0 and will be removed in a future major release. Use Services Condition or Services Module Input instead. See 0.5.0 release notes for examples. Specifies an optional list of logical service names or service IDs that the task monitors for changes in the Consul catalog. Theservices
can act in different ways depending on the configuration of the task'scondition
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 typeservices
:services
is incompatible with this type ofcondition
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 thedefault
namespace.- no
source
- (string: required) Deprecated in CTS 0.5.0 and will be removed in a future major release. See themodule
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 or private module registry. Read more on Terraform module source and other supported types here.To use a private module with the
terraform
driver, run the commandterraform login [hostname]
to authenticate the local Terraform CLI prior to starting CTS.To use a private module with the
terraform_cloud
driver, no extra steps are needed.// 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
). 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.example.tfvars
address_group = "consul-services"tags = [ "consul-terraform-sync", "terraform"]
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 baseworking_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 levelbuffer_period
block. 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. Specifyingmin
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. Ifmin
is set, the default period formax
is 4 times the value ofmin
.
condition
- (obj: required) The requirement that, when met, triggers CTS to execute the task. Only onecondition
may be configured per task. CTS supports different types of conditions, which each have their own configuration options. See 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. See themodule_input
block instead.module_input
- (obj) Specifies a Consul object containing values or metadata to be provided to the Terraform Module. Themodule_input
block defines any extra module inputs needed for task execution. This is in addition to any module input provided by thecondition
block orservices
field (deprecated). Multiplemodule_input
blocks can be configured per task. Task Module Input configuration for full details on usage and restrictions.terraform_version
- (string) Enterprise Deprecated in CTS 0.6.0 and will be removed in 0.8.0. Reviewterraform_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; otherwise, set the version within the Terraform driver.terraform_cloud_workspace
- (obj) Enterprise Configures attributes of the Terraform Cloud workspace associated with the task. This option is only available when used with the Terraform Cloud driver. For global configurations of all workspaces, reviewdriver.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 ifexecution_mode
is set to "agent". The ID of the agent pool that should run the Terraform workloads. Eitheragent_pool_id
oragent_pool_name
are required ifexecution_mode
is set to "agent".agent_pool_id
takes precedence overagent_pool_name
if both are provided.agent_pool_name
- (string) Only supported ifexecution_mode
is set to "agent". The name of the agent pool that should run the Terraform workloads. Only supported ifexecution_mode
is set to "agent". Eitheragent_pool_id
oragent_pool_name
are required.agent_pool_id
takes precedence overagent_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"
orsource_input "services"
(deprecated) block
These restrictions are due to the fact that 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.
See Task Execution: Services Condition for more details on how tasks are triggered with a services condition.
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" } }}
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. 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 | Enterprise Namespace of the services to query for the task. | In order of precedence: 1. Inferred from the CTS ACL token 2. The default namespace. |
filter | Optional | string | Expression used to additionally filter the services to monitor. Refer to the services filtering documentation and section about how to write filter expressions for additional information. | none |
cts_user_defined_meta | Optional | map[string] | User-defined metadata that is appended to the service input variable for compatible Terraform modules. 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. See 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 for the Terraform modulePlease 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.
See Task Execution: Catalog Services Condition for more information on how tasks are triggered with a catalog-services condition.
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. Refer to regular expression syntax documentation and try out regular expression string matching 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 | Enterprise Namespace of the services to query for the task. | In order of precedence: 1. Inferred from the CTS ACL token 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. See 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 for the Terraform modulePlease 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.
See Task Execution: Consul KV Condition for more information on how tasks are triggered with a consul-kv condition.
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 | Enterprise Namespace of the services to query for the task. | In order of precedence: 1. Inferred from the CTS ACL token 2. The default namespace. |
source_includes_var | Optional | boolean | Deprecated in CTS 0.5.0 and will be removed in 0.8.0. See 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 for the Terraform modulePlease 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. See module_input
block configuration for details on how to configure module input.
See Task Execution: Schedule Condition for more information on how tasks are triggered with schedule conditions.
See Terraform Module: Module Input for more information on module input options for a scheduled task.
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, see the cronexpr parsing library. | none |
Task Module Input
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.
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:
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). See Task Module Input Restrictions for more details.
The following sections describe the module input types that CTS supports.
Services Module Input
This services
module input object defines services registered to Consul whose metadata will be used as services module input to the Terraform Module. 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. 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 | Enterprise String value indicating the namespace of the services to query for the task. | In order of precedence: 1. Inferred from the CTS ACL token 2. The default namespace. |
filter | Optional | string | Expression used to additionally filter the services to monitor. Refer to the services filtering documentation and section about how to write filter expressions for additional information. | none |
cts_user_defined_meta | Optional | map[string] | User-defined metadata that is appended to the service input variable for compatible Terraform modules. 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.
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
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. 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 | Enterprise Namespace of the services to query for the task. | In order of precedence: 1. Inferred from the CTS ACL token 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
.
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
andmodule_input
block of the same type. For example, configuringcondition "consul-kv"
andmodule_input "consul-kv"
will error because both configure theconsul_kv
variable.A task cannot be configured with two or more
module_input
blocks of the same type. For example, configuring twomodule_input "catalog-services"
within a task will return an error because they define multiple configurations for thecatalog_services
variable.A task that monitors services can only contain one of the following configurations:
condition "services"
blockmodule_input "services"
block- Block was previously named
source_input "services"
(deprecated)
- Block was previously named
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 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.
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 for each task. This option is similar to the Terraform backend configuration. CTS supports Terraform backends used as a state store.- Supported backend options: azurerm, consul, cos, gcs, kubernetes, local, manta, pg (Terraform v0.14+), 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 to configure Consul as the backend, which stores Terraform statefiles in the Consul KV. The ACL token provided for Consul authentication is used to read and write to the KV store and requires Consul KV privileges. 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 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 islocal
, 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 settingTF_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 Terraformterraform.required_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. 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
This feature requires Consul-Terraform-Sync Enterprise which is available with Consul Enterprise.
The Terraform Cloud driver enables CTS Enterprise to integrate with Terraform Cloud, including both the self-hosted distribution and the managed service. 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 documentation.
Only one network driver can be configured per deployment of CTS.
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 theTFC_HOSTNAME
environment variable.organization
- (string) The Terraform Cloud organization that hosts the managed workspaces by CTS. Can be overridden with theTFC_ORGANIZATION
environment variable.token
- (string) Required Team API token used for authentication with Terraform Cloud and workspace management. Only workspace permissions are needed for CTS. The token can also be provided using theTFC_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 theworkspaces.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 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 thetags_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 Terraformterraform.required_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.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 bycert
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
orca_path
. Alternatively, you can disable SSL verification by settingverify
to false. However, disabling verification is a potential security vulnerability.tls { verify = false}
- 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
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
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 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. 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.
The below configuration captures the general design of defining a provider using the AWS Terraform provider as an example.
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
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
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 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.
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\" }}" }}
Security note: 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
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.
Load Dynamic Values
Load dynamic values for Terraform providers with integrated template syntax.
Env
env
reads the given environment variable accessible to CTS.
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.
terraform_provider "example" { value = "{{ key \"path/example/key\" }}"}
Vault
with secret
queries the Vault KV secrets engine. Vault is an optional source that require operators to configure the Vault client with a vault
block. Access the secret using template dot notation Data.data.<secret_key>
.
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 theVAULT_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 theVAULT_NAMESPACE
environment variable.renew_token
- (bool) Renews the Vault token. This can also be set via theVAULT_RENEW_TOKEN
environment variable.tls
- (tls block) TLS indicates the client should use a secure connection while talking to Vault. Supports the environment variables: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 theVAULT_TOKEN
environment variable, or via theVaultAgentTokenFile
.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 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.
Multiple Provider Configurations
CTS supports the Terraform feature to define multiple 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
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.
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"] // ...}