Skip to main content

Create a Courier jobs template

A Courier job template defines a job in a JSON file with the job metadata, a schedule, targets, and actions.

Create a job template

Job metadata

Define a job using a unique name and job description.

Use the following parameters:

name
A unique name for the template.

Type: string

description
A plain text description of the template.

Type: string

This example defines a job template name and description:

{
  "name":"multi_group_parallel_scheduled",
  "description": "An integration test: demonstrating one group batch size fixed 5",
  ...

Job schedule

You can schedule jobs to run immediately or on a schedule.

Examples:

  • A job is scheduled to run immediately after a current run completes.
  • A job is scheduled to run on a specified date and time after a current run completes. For example, run this job on 1st January 2024 at 1 AM.
  • A job runs multiple times on the specified date (or dates) and time (or times). Each occurrence of this schedule is an instance of the job. For example, every Monday of the week from 1st January to 1st May 2024, and every day of the month of April in 2024 at 3 PM.

Use the following parameters to schedule a job:

scheduleRule
Either the string immediate, or a valid RFC-5545 recurrence rule including the RRULE: prefix. This value determines when and how often this job is initiated. When value is immediate the job is executed as soon as possible and doesn’t have any recurrence.

Type: string

Example:

"scheduleRule": "RRULE:FREQ=DAILY;INTERVAL=2",
exceptionRules
RFC-5545 recurrence rules that are applied to exclude job execution during the specified time windows. Each exception must include the recurrence rule and the duration in minutes that the exception lasts.

Type: array

Example:

"exceptionRules":[{
  "rrule": "RRULE:FREQ=MINUTELY;INTERVAL=10;COUNT=5",
  "duration": 60}
],

This example defines a schedule rule and exception rule:

  ...
  "scheduleRule": "RRULE:FREQ=MINUTELY;INTERVAL=10;COUNT=20",
  "exceptionRules":[{
    "rrule": "RRULE:FREQ=MINUTELY;INTERVAL=10;COUNT=5",
    "duration": 60}
  ],
  ...

Job targets

A node distribution group is a list of node reference IDs. The job runs are specific to the Node IDs provided by the user, a node filter, node list, or query that resolves to a set of node IDs.

Use the following properties to target groups of nodes:

target
Indicates the job targets.

Type: object

target.executionType
The execution types across distribution groups:
  • sequential: runs are performed on node distribution groups one after the other, in the order provided, and after validating that the success conditions of each distribution group have been met.
  • parallel: runs each distribution group in parallel, respecting the distribution.

In both cases, the distributionMethod within a group determines how the work is distributed to nodes. See distributionMethod for more details.

Type: enum

Possible values: sequential, parallel

target.groups
The groups to apply this template to.

Type: array

target.groups.[].timeoutSeconds
How long to wait (in seconds) for all actions in a job run to complete for each batch of nodes in the distribution group. Any job run exceeding this time is marked with status timeout and is no longer monitored for further updates. This time starts when the request is sent to the client.

Type: integer

Default value: 3600

Minimum: 1

Maximum: 86399

target.groups.[].batchSize
Determines how many job runs (expressed as a percent or absolute value) are executed within each batch. If the value is a percent of all runs in the instance, it is rounded down. Only the number of nodes specified in a batch size can execute runs together and the rest in the node distribution group must wait for their batch.

Type: object

target.groups.[].batchSize.type
The batch size type:
  • number: an integer value of the number of nodes in a batch. For example, five nodes for each node distribution group.
  • percent: a percentage of nodes within a node distribution group. For example, 10 percent of nodes for each node distribution group.

Type: enum

Possible values: percent, number

target.groups.[].batchSize.value
The integer value of nodes included in a distribution group.

Type: integer

target.groups.[].distributionMethod
How to distribute work to nodes within a distribution group:
rolling
Work is distributed such that ‘batchSize’ nodes are always running the job, until all nodes in the group have completed. As any node completes execution, another starts to maintain a steady running size of ‘batchSize’.

For example:

  1. There is a batch size of five for the following node distribution group: a,b,c,d,e,f,g,h,i,j,k.
  2. Job runs are performed first on a,b,c,d, and e together.
  3. Whenever any node within this batch completes a job execution, it’s removed from the batch and the job run begins on f.
batching
Work is distributed such that nodes within the group are started in batches of ‘batchSize’. The next batch doesn’t begin until all nodes in the prior batch have completed execution or timed out.

For example:

  1. There’s a batch size of 5 for the following node distribution group: a,b,c,d,e,f,g,h,i,j,k.
  2. Job runs are performed first on a,b,c,d, and e together.
  3. After all five nodes complete, then f,g,h,i, and j execute together.
  4. The job run only happens on node k after the completion of the second batch.

Type: enum

Possible values: rolling, batching

target.groups.[].successCriteria
Conditions under which this distribution group is considered to have successfully executed. All criterion must be met for it to evaluate successful (logical AND is applied across conditions). This is used in capturing distribution group results and determining if execution should proceed to the next distribution group in the case of a sequential execution type.

Type: array

target.groups.[].successCriteria.[].status
The expected status.

Type: string

Possible values: success, failure

target.groups.[].successCriteria.[].numRuns
The number of job runs that are expected to match the given status for this SuccessCriteria to evaluate as true.

Possible values:

  • number: an integer value of the number of job runs that must match the given status.
  • percent: a percentage of job runs that must match the given status.

Type: enum

target.groups.[].batchSize.value
The integer value of nodes included in a distribution group.

Type: integer

target.groups.[].nodeListType
Controls how the node list is resolved.

Allowed values are as follows:

  • filter
  • savedFilter
  • savedList
  • nodes

Depending on the value, you must also set the following:

  • if set to filter, add a filter in filter
  • if set to savedFilter, add a filter ID in filterId
  • if set to savedList, provide a list ID in listId
  • if set to nodes, provide a list of node IDs in nodeIdentifiers.

Type: enum

target.groups.[].filter
An adhoc filter. Required if nodeListType is set to filter.

It must comply with the Node.FilterExec schema as defined in the node-management API specification. This ad-hoc filter is expanded when orchestrator-worker picks up a job instance for execution.

Type: object

target.groups.[].filterId
The UUID of a node filter. Required if nodeListType is set to savedFilter.

Type: string

This identified filter is expanded when orchestrator-worker picks up a job instance for execution.

target.groups.[].listId
The UUID of a node list. Required if nodeListType is set to savedList.

Type: string

This identified list is expanded when orchestrator-worker picks up a job instance for execution.

target.groups.[].nodeIdentifiers
An array of node UUID identifiers. This is a fixed list and isn’t evaluated or expanded further.

Required if nodeListType is set to nodes.

Type: array

Minimum size: 1

This example defines two target groups where actions are run sequentially:

  ...
  "target": {
    "executionType": "sequential",
    "groups":[
        {
            "timeoutSeconds": 240,
            "batchSize": {
                "type": "number",
                "value": 1
            },
            "distributionMethod": "batching",
            "successCriteria": [
                {
                    "numRuns": { "type": "percent", "value": 100 },
                    "status": "success"
                }
            ],
            "nodeListType":"nodes",
            "nodeIdentifiers":[
                "5a222a24-ed1d-42dc-83d1-770c3ad7d09d"
            ]
        },
        {
            "timeoutSeconds": 120,
            "batchSize": {
                "type": "number",
                "value": 1
            },
            "distributionMethod":"batching",
            "successCriteria": [{ "numRuns": { "type": "percent", "value": 100 }, "status": "success" }],
            "nodeListType":"nodes",
            "nodeIdentifiers":[
                "6253d757-362a-487c-9cf3-9311f8bad0b7"
            ]
        }
    ]
  },
  ...

Job actions

Job actions define everything that happens on a node before, during, and after a job run.

You can chain multiple actions in a job. These actions are executed sequentially by default. However, each action can have a condition to check on the results of the previous action. For example, perform a remediation action only if the previous compliance scan action failed or execute an anti-virus scan action after the previous action completes.

Use the following parameters to define job actions:

actions
The workloads with corresponding payloads to be executed by every node during a job run. There can be multiple actions for each job run. Actions are always performed sequentially as defined in the job.

Type: object

actions.steps
The steps to perform on the target nodes. Provide at least one step.

Type: array

actions.steps.[].name
A short name that provides the intent of this step.

Type: string

minLength: 1

maxLength: 128

example: install-nginx

actions.steps.[].description
An optional field providing a more detailed description of this step.

Type: string

minLength: 1

maxLength: 1024

actions.steps.[].command
One or more commands appropriate to the specified interpreter. Provide at least one command.

For example, a list of commands to be run by the OS command skill or the cookbook to be run by Chef Infra Client.

Type: object

Example: { "exec": "machine_reboot", "args": { "time": 90 } }

actions.steps.[].inputs
A name -> string value object that provides pre-set inputs and their values to this action/step.

Pre-defined inputs to the action, independent of prior steps. The agent prioritizes inputs from previous steps over those provided in the definition. Note that sensitive inputs aren’t redacted when sent from the Courier Server to the agent.

This field is optional and can be omitted if no additional inputs are necessary.

Type: object

Example:

"inputs": {"listen_port": "8080", "accesstoken": "ABCD"},
actions.steps.[].expectedInputs
An object mapping of expected input field names to their definitions.

This field is optional and can be omitted if there are no expected inputs.

Type: object (string, ExpectedStepInput)

Example: { "passwd": { "required": false, "sensitive": true } }

actions.steps.[].expectedInputs.[].default
Default value, used if no value is provided.

Type: string

Example: “value1”

actions.steps.[].expectedInputs.[].required
The value true or false, specifying whether the field is required or not. If this value is required and not provided and not defaulted, this step fails without executing.

Type: boolean

Default: true

actions.steps.[].expectedInputs.[].sensitive
Whether the field is sensitive or not. If true, the value of this input must be redacted before submitting to Courier as part of inputs in the payload, and before writing to any local log files.

Type: boolean

Default: false

actions.steps.[].outputFieldRules
This describes how to process the step’s output to extract the required output field value. The key and extracted value can be provided to the next step as an input.

This field is optional and can be omitted if there are no expected inputs.

Type: object

actions.steps.[].outputFieldRules.sourceType
Describes what type of source the output field value is extracted from. Combined with source, this is used to assign the output field value.

Possible values:

  • artifact: the output field value is extracted from an artifact.
  • exitCode: the output field value is the exit code of the step.
  • file: the output field value is extracted from a file.
  • output: the output field value is extracted from the standard output or standard error streams of the step.

Type: enum

actions.steps.[].outputFieldRules.source
Where the output field value comes from. This is dependent on sourceType.
  • If sourceType is artifact, then source must be a path, for example source="/tmp/path/file.log".
  • If sourceType is exitCode, then the source property isn’t used.
  • If sourceType is file, then source must be a path, such as source="/tmp/path/file.txt".
  • If sourceType is output, then source must be the output name, either stdout or stderr.

Type: string

actions.steps.[].outputFieldRules.extractMethod
The method to extract the output:
  • regex: a regular expression to run against source to extract the field value.

  • jsonPath: parse source as JSON and extract the value using the path specified in expression.

  • content: include the full content of source based on sourceType.

    • If sourceType is artifact, then extractMethod yields the full content of the artifact.
    • If sourceType is exitCode, then extractMethod is treated as content and yields the exit code itself.
    • If sourceType is file, then extractMethod yields the full content of the file.
    • If sourceType is output, then extractMethod yields the full output (stdout or stderr based on source).

    Note that content is intended for small payloads (measured in tens of bytes or less) since it is used for comparison purposes in subsequent steps.

Type: enum

Possible values: regEx, jsonPath, content

actions.steps.[].outputFieldRules.expression
The expression to apply to source using extractMethod to extract the value.

If extractMethod is set to:

  • regEx, define a regular expression to extract the value.

  • jsonPath, define a JSON path to the value.

  • content, then the full content of source is based on the sourceType:

    • If sourceType is artifact, then content includes the full content of the artifact.
    • If sourceType is exitCode, then content is the exit code value of the step.
    • If sourceType is file, then content is the full content of the file.
    • If sourceType is output, then content includes everything emitted from the standard output or standard error output stream.

Type: string

Example: .example.files[0].name

actions.steps.[].outputFieldRules.required
When true, fail this step if the client/interpreter can’t extract the field value for any reason.

Type: boolean

actions.steps.[].outputFieldRules.sensitive
When true, the value of this input must be redacted before submitting to Courier as part of outputs in the payload, and before writing to any local log files.

Type: boolean

actions.steps.[].retryCount
The maximum number of times to retry this step in the event of local failure. Retry behavior and handling depends on the failureBehavior property.

For example, set the number of retries to stop a background process to 5 because it might not stop the first time.

Type: integer

Default value: 1

actions.steps.[].failureBehavior
Indicates what to do when this action fails.

Type: object (StepFailureBehavior)

actions.steps.[].failureBehavior.action
The action to take if a step fails.

Possible values:

  • retryThenFail

    Retry according to retry rules. If the step is still failing after retries are exhausted or retryCount is 0, fail this step and abort the job run.

  • retryThenIgnore

    Retry according to retry rules. If the step is still failing after retries are exhausted or retryCount is 0, update this step as having failed and continue to the next step.

Type: enum

actions.steps.[].failureBehavior.retryBackoffStrategy
Retry and backoff strategy to use while attempting to retry up to retryCount times.

Type: object

actions.steps.[].failureBehavior.retryBackoffStrategy.type
The retry backoff strategy type.

Allowed values are as follows:

  • none for no backoff - retry after the duration specified by delaySeconds without modification
  • linear for backoff, such as (delaySeconds * attemptNumber)
  • exponential delaySeconds^attemptNumber
  • polynomial attemptNumber^x, where x is provided as the first element of arguments. Each attempt uses the next number in arguments as x.

Type: enum

Possible values: none, linear, exponential, polynomial

Default value: linear

actions.steps.[].failureBehavior.retryBackoffStrategy.arguments
An array of arguments required for the specified retry backoff strategy type.

Type: array

actions.steps.[].failureBehavior.retryBackoffStrategy.delaySeconds
The base delay (in seconds) between each retry/attempt. This may be modified based on the behavior of the strategy and its arguments.

Type: integer

actions.steps.[].limits
An object defining the limits that a step can’t exceed. The action stops execution of the step when the limit is crossed. There can be multiple limits for each action.

For example, don’t run the step in more than one core.

Type: object

actions.steps.[].limits.cores
The number of cores to make available to the interpreter and any child processes for this step. The default is 0 for ‘all’.

Type: integer

Default value: 0

Example: 1

actions.steps.[].limits.cpu
The amount of CPU (0.0–1.0) that the interpreter and children can use in this step. The default is 1.0, which is unlimited.

Type: float

Default value: 1.0

Minimum: 0.0

Maximum: 1.0

actions.steps.[].limits.timeoutSeconds
The time limit in seconds. If the execution time exceeds this, the action is considered as failed, the agent cleanly ends the action, and retry rules apply. A value of 0 means there is no time limit.

Type: integer

Default value: 0

actions.steps.[].conditions
An array of conditions that must all evaluate to true. If a condition evaluates to false, the step is skipped.

Type: array

actions.steps.[].conditions.[].inputName
The name of the input value to evaluate using the operator and condition values. Maps to ExpectedInputs[inputName].

Type: string

actions.steps.[].conditions.[].negate
Whether to negate the comparison operator. For example, when true, eq is evaluated as ’not equal to’.

Type: boolean

Default value: false

actions.steps.[].conditions.[].operator
Operator to apply when making the comparison. Note that ranges can be accommodated with multiple conditions, such as ‘value lte 10’ and ‘value gte 0’.

Type: enum

Possible values:

  • eq
  • gt
  • gte
  • lt
  • lte
  • matches
  • startsWith
  • endsWith
  • contains.
actions.steps.[].conditions.[].value
The literal value to compare against, or the name of another input field prefixed with $.

For example, inputName of ‘inputZero’ ’eq’ ‘$inputOne’ it evaluates to true if the value of input ‘inputOne’ equals the value of ‘inputZero’. To compare the literal $ at the start of a value, use $$. For example, eq $$value1 evaluates true if input == '$value1'.

Type: string

This example defines a single action with one step:

  ...
  "actions": {
      "accessMode": "agent",
      "steps":
      [
          {
              "name": "sleep",
              "stepNumber": 1,
              "interpreter": {
                  "name": "chef-platform/shell-interpreter"
              },
              "command": {
                "linux": [
                  "sleep 10"
                ]
              },
              "inputs": {},
              "expectedInputs": { },
              "OutputFieldRules": {},
              "retryCount": 2,
              "failureBehavior": {
                  "action": "retryThenFail",
                  "retryBackoffStrategy": {
                      "type": "none",
                      "delaySeconds": 0,
                      "arguments": [1,3,5]
                  }
              },
              "limits": {},
              "conditions": [
              ]
          }
      ]
  },

Job template example

The following is an example job template.

Some of these parameters conflict with each other and can’t be included in the same job. For details, see the section on creating a job template.

{
  "name":"<STRING>",
  "description": "<STRING>",
  "scheduleRule": "<STRING>",
  "exceptionRules": [],
  "target": {
    "executionType": "<ENUM>",
    "groups":[
      {
        "timeoutSeconds": <INTEGER>,
        "batchSize": {
          "type": "<ENUM>",
          "value": <INTEGER>
        },
        "distributionMethod": "<ENUM>",
        "successCriteria": [
          {
            "numRuns": {
              "type": "<ENUM>",
              "value": <INTEGER>
            },
            "status": "<ENUM>"
          }
        ],
        "nodeListType": "<ENUM>",
        "filter": <OBJECT>,
        "listId": "<UUID>",
        "filterId": "<UUID>",
        "nodeIdentifiers":[
          "<UUID>"
        ]
      }
    ]
  },
  "actions": {
    "accessMode": "agent",
    "steps":
    [
      {
        "name": "<STRING>",
        "description": "<STRING>",
        "command": {},
        "inputs": {},
        "interpreter": {
          "skill": {
            "minVersion": "",
            "maxVersion": ""
          },
          "name": ""
        },
        "expectedInputs": {
          "<INPUT_NAME>": {
            "default": "<STRING>",
            "required": <BOOLEAN>,
            "sensitive": <BOOLEAN>
          }
        },
        "outputFieldRules": {
          "sourceType": "<ENUM>",
          "source": "<STRING>",
          "extractMethod": "<ENUM>",
          "expression": "<STRING>",
          "required": <BOOLEAN>,
          "sensitive": <BOOLEAN>
        },
        "retryCount": <INTEGER>,
        "failureBehavior": {
          "action": "<ENUM>",
          "retryBackoffStrategy": {
            "name": "<ENUM>",
            "delaySeconds": <INTEGER>,
            "arguments": []
          }
        },
        "limits": {
          "cores": <INTEGER>,
          "cpu": <FLOAT>,
          "timeoutSeconds": <INTEGER>,
        },
        "conditions": [
          {
            "inputName": "<STRING>",
            "negate": <BOOLEAN>,
            "operator": "<ENUM>",
            "value": "<STRING>"
          }
        ]
      }
    ]
  }
}

Thank you for your feedback!

×











Search Results