Tasks

    Below is an example task configuration:

    1. name = "frontend-firewall-policies"
    2. description = "Add firewall policy rules for frontend services"
    3. providers = ["fake-firewall", "null"]
    4. module = "example/firewall-policy/module"
    5. version = "1.0.0"
    6. condition "services" {
    7. names = ["web", "image"]
    8. }
    9. }

    In the example task above, the “fake-firewall” and “null” providers, listed in the providers field, are used. These providers themselves should be configured in their own separate terraform_provider blocks. These providers are used in the Terraform module “example/firewall-policy/module”, configured in the module field, to create, update, and destroy resources. This module may do something like use the providers to create and destroy firewall policy objects based on IP addresses. The IP addresses come from the “web” and “image” service instances configured in the condition "services" block. This service-level information is retrieved by CTS which watches Consul catalog for changes.

    See for more details on how to configure a task.

    A task can be either enabled or disabled using the task cli. When enabled, tasks are executed and automated as described in sections below. However, disabled tasks do not execute when changes are detected from Consul catalog. Since disabled tasks do not execute, they also do not store until re-enabled.

    An enabled task can be configured to monitor and execute on different types of conditions, such as changes to services (services condition) or service registration and deregistration ().

    A task can also monitor, but not execute on, other variables that provide additional information to the task’s module. For example, a task with a catalog-services condition may execute on registration changes and additionally monitor service instances for IP information.

    All configured monitored information, regardless if it’s used for execution or not, can be passed to the task’s module as module input. Below are details on the types of execution conditions that CTS supports and their module inputs.

    Tasks with the services condition monitor and execute on either changes to a list of configured services or changes to any services that match a given regex.

    There are two ways to configure a task with a services condition. Only one of the two options below can be configured for a single task:

    1. Configure a task’s services field (deprecated) to specify the list of services to trigger the task
    2. Configure a task’s condition block with the type to specify services to trigger the task.

    The services condition operates by monitoring the Health List Nodes For Service API and executing the task on any change of information for services configured. These changes include one or more changes to service values, like IP address, added or removed service instance, or tags. A complete list of values that would cause a task to run are expanded below:

    Below is an example configuration for a task that will execute when a service with a name that matches the regular expression has a change.

    1. task {
    2. name = "services_condition_task"
    3. description = "execute on changes to services whose name starts with web"
    4. providers = ["my-provider"]
    5. module = "path/to/services-condition-module"
    6. condition "services" {
    7. regexp = "^web.*"
    8. use_as_module_input = false
    9. }
    10. }
    1. task {
    2. name = "services_condition_task"
    3. description = "execute on changes to services whose name starts with web"
    4. providers = ["my-provider"]
    5. module = "path/to/services-condition-module"
    6. condition "services" {
    7. regexp = "^web.*"
    8. use_as_module_input = false
    9. }
    10. }

    The services condition can provide input for the that is required for each CTS module. This can be provided depending on how the services condition is configured:

    • task’s services field (deprecated): services object is automatically passed as module input
    • task’s condition "services" block: users can configure the use_as_module_input field to optionally use the condition’s services object as module input
      • Field was previously named source_includes_var (deprecated)

    Catalog-Services Condition

    Tasks with a catalog-services condition monitor and execute on service registration changes for services that satisfy the condition configuration. ‘Service registration changes’ specifically refers to service registration and deregistration where service registration occurs on the first service instance registration, and service deregistration occurs on the last service instance registration. Tasks with a catalog-services condition may, depending on the module, additionally monitor but not execute on service instance information.

    The catalog-services condition operates by monitoring the and executing the task when services are added or removed in the list of registered services. Note, the task does not execute on changes to the tags of the list of services. This is similar to how changes to service instance information, mentioned above, also does not execute a task.

    1. task {
    2. name = "catalog_service_condition_task"
    3. providers = ["my-provider"]
    4. condition "catalog-services" {
    5. datacenter = "dc1"
    6. regexp = "web.*"
    7. use_as_module_input = false
    8. }
    9. module_input "services" {
    10. names = ["web-api"]
    11. datacenter = "dc2"
    12. }
    13. }

    Using the condition block’s use_as_module_input field, users can configure CTS to use the condition’s object as module input for the catalog_services input variable. Users can refer to the configured module’s documentation on how to set use_as_module_input.

    See the configuration section for further details and additional configuration options.

    Tasks with a consul-kv condition monitor and execute on Consul KV changes for KV pairs that satisfy the condition configuration. The consul-kv condition operates by monitoring the Consul KV API and executing the task when a configured KV entry is created, deleted, or updated.

    Based on the recurse option, the condition either monitors a single Consul KV pair for a given path or monitors all pairs that are prefixed by that path. In the example below, because recurse is set to true, the path option is treated as a prefix. Changes to an entry with the key my-key and an entry with the key my-key/another-key would both trigger the task. If recurse were set to false, then only changes to my-key would trigger the task.

    1. task {
    2. name = "consul_kv_condition_task"
    3. description = "execute on changes to Consul KV entry"
    4. module = "path/to/consul-kv-module"
    5. providers = ["my-provider"]
    6. condition "consul-kv" {
    7. path = "my-key"
    8. recurse = true
    9. datacenter = "dc1"
    10. namespace = "default"
    11. use_as_module_input = true
    12. }
    13. }
    1. task {
    2. name = "consul_kv_condition_task"
    3. description = "execute on changes to Consul KV entry"
    4. module = "path/to/consul-kv-module"
    5. providers = ["my-provider"]
    6. condition "consul-kv" {
    7. path = "my-key"
    8. recurse = true
    9. datacenter = "dc1"
    10. namespace = "default"
    11. use_as_module_input = true
    12. }
    13. }

    Using the condition block’s use_as_module_input field, users can configure CTS to use the condition’s object as module input for the . Users can refer to the configured module’s documentation on how to set use_as_module_input.

    See the Consul-KV Condition configuration section for more details and additional configuration options.

    Schedule Condition

    All scheduled tasks must be configured with a schedule condition. The schedule condition sets the cadence to trigger a task with a cron configuration. The schedule condition block does not support parameters to configure module input. As a result, inputs must be configured separately. You can configure to define the module inputs.

    Below is an example configuration for a task that will execute every Monday, which is set by the schedule condition’s cron configuration. The module input is defined by the module_input block. When the task is triggered on Monday, it will retrieve the latest information on “web” and “db” from Consul and provide this to the module’s input variables.

    1. task {
    2. name = "scheduled_task"
    3. module = "path/to/module"
    4. condition "schedule" {
    5. cron = "* * * * Mon"
    6. }
    7. module_input "services" {
    8. names = ["web", "db"]
    9. }
    10. }
    1. task {
    2. name = "scheduled_task"
    3. description = "execute every Monday using service information from web and db"
    4. condition "schedule" {
    5. cron = "* * * * Mon"
    6. }
    7. module_input "services" {
    8. names = ["web", "db"]
    9. }
    10. }

    Below are the available options for module input types and how to configure them:

    • :
      • task.services field (deprecated)
      • block
        • Block was previously named source_input "services" (deprecated)
    • Consul KV module input:
        • Block was previously named source_input "consul-kv" (deprecated)

    Running Behavior

    Scheduled tasks generally run on schedule, but they can be triggered on demand when running CTS in the following ways:

    • : At the beginning of the long-running mode, CTS first passes through a once-mode phase in which all tasks are executed once. Scheduled tasks will trigger once during this once-mode phase. This behavior also applies to tasks that are not scheduled. After once-mode has completed, scheduled tasks subsequently trigger on schedule.

    • Inspect mode: When running in inspect mode, the terminal will output a plan of proposed updates that would be made if the tasks were to trigger at that moment and then exit. No changes are applied in this mode. The outputted plan for a scheduled task is also the proposed updates that would be made if the task was triggered at that moment, even if off-schedule.

    • : During the once mode, all tasks are only triggered one time. Scheduled tasks will execute during once mode even if not on the schedule.

    • Enable CLI: When a task is enabled through the CLI, any type of task, including scheduled tasks, will be triggered at that time.

    Buffer Period

    Events

    are stored each time a task executes. For scheduled tasks, an event will be stored each time the task triggers on schedule regardless of if there was a change in Consul catalog.

    CTS will attempt to execute each enabled task once upon startup to synchronize infrastructure with the current state of Consul. The daemon will stop and exit if any error occurs while preparing the automation environment or executing a task for the first time. This helps ensure tasks have proper configuration and are executable before the daemon transitions into running tasks in full automation as service changes are discovered over time. As a result, it is not recommended to configure a task as disabled from the start. After all tasks have successfully executed once, task failures during automation will be logged and retried or attempted again after a subsequent change.

    Tasks are executed near-real time when service changes are detected. For services or environments that are prone to flapping, it may be useful to configure a buffer period for a task to accumulate changes before it is executed. The buffer period would reduce the number of consecutive network calls to infrastructure by batching changes for a task over a short duration of time.

    Status-related information is collected and offered via to provide visibility into what and how the tasks are running. Information is offered in three-levels (lowest to highest):

    • Event data
    • Task status
    • Overall status

    These three levels form a hierarchy where each level of data informs the one higher. The lowest-level, event data, is collected each time a task runs to update network infrastructure. This event data is then aggregated to inform individual task statuses. The count distribution of all the task statuses inform the overall status’s task summary.

    When a task is triggered, CTS takes a series of steps in order to update the network infrastructure. These steps consist of fetching the latest data from Consul for the task’s module inputs and then updating the network infrastructure accordingly. An event captures information across this process. It stores information to help understand if the update to network infrastructure was successful or not and any errors that may have occurred.

    A dynamic task will store an event when it is triggered by a change in Consul. A scheduled task will store an event when it is triggered on schedule, regardless if there is a change in Consul. A disabled task does not update network infrastructures, so it will not store events until until re-enabled.

    Sample event:

    1. {
    2. "id": "ef202675-502f-431f-b133-ed64d15b0e0e",
    3. "success": false,
    4. "start_time": "2020-11-24T12:05:18.651231-05:00",
    5. "end_time": "2020-11-24T12:05:20.900115-05:00",
    6. "task_name": "task_b",
    7. "error": {
    8. "message": "example error: error while doing terraform-apply"
    9. },
    10. ...
    11. }

    For complete information on the event structure, see events in our API documentation. Event information can be retrieved by using the with the task status API.

    Task Status

    Each time a task runs to update network infrastructure, event data is stored for that run. 5 most recent events are stored for each task, and these stored events are used to determine task status. For example, if the most recent stored event is not successful but the others are, then the task’s health status is “errored”.

    Sample task status:

    1. {
    2. "task_name": "task_b",
    3. "status": "errored",
    4. "providers": ["null"],
    5. "services": ["web"],
    6. "events_url": "/v1/status/tasks/task_b?include=events"
    7. }
    1. {
    2. "task_name": "task_b",
    3. "status": "errored",
    4. "providers": ["null"],
    5. "services": ["web"],
    6. "events_url": "/v1/status/tasks/task_b?include=events"
    7. }

    Task status information can be retrieved with task status API. The API documentation includes details on what health statuses are available and how it is calculated based on events’ success/failure information.

    Overall status returns a summary of the health statuses across all tasks. The summary is the count of tasks in each health status category.

    Sample overall status:

    1. {
    2. "task_summary": {
    3. "successful": 28,
    4. "errored": 5,
    5. "critical": 1
    6. }