Create a Chef Courier job template
A Chef Courier job template defines a job in a JSON, YAML, or TOML file with the job metadata, a schedule, targets, and actions.
Courier job parameters
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",
  ...
name: multi_group_parallel_scheduled
description: 'An integration test: demonstrating one group batch size fixed 5'
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 theRRULE:prefix. This value determines when and how often this job is initiated. When value isimmediatethe job is executed as soon as possible and doesn’t have any recurrence.Type: string
Example:
"scheduleRule": "RRULE:FREQ=DAILY;INTERVAL=2", exceptionRules- An array of exception rules to exclude job executions during the specified time windows.
Each exception must include an RFC-5545 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 schedule and exception rules:
...
"scheduleRule": "RRULE:FREQ=MINUTELY;INTERVAL=10;COUNT=20",
"exceptionRules":[{
  "rrule": "RRULE:FREQ=MINUTELY;INTERVAL=10;COUNT=5",
  "duration": 60}
],
...
scheduleRule: 'RRULE:FREQ=MINUTELY;INTERVAL=10;COUNT=20'
exceptionRules:
- rrule: 'RRULE:FREQ=MINUTELY;INTERVAL=10;COUNT=5'
  duration: 60
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
distributionMethodwithin a group determines how the work is distributed to nodes. Seetarget.groups.[].distributionMethodfor 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 
timeoutand is no longer monitored for further updates. This time starts when the request is sent to the client.Type: integer
Default value:
3600Minimum:
1Maximum:
86399 target.groups.[].batchSize- Determines how many job runs (expressed as a percentage or absolute value) are executed within each batch.
If the value is a percentage of all runs in the instance, it’s 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.
Type: enum
Possible values:
rolling,batching.rolling- Work starts on a batch of nodes whose size is determined by 
batchSize. As a node in the batch completes the job, another starts so that the number of nodes executing the job continues to be the size defined bybatchSize. This continues until all nodes in the group have completed the job.For example:
- There is a batch size of five for the following node distribution group: a, b, c, d, e, f, g, h, i, j, k.
 - Job runs are performed first on any five nodes, for example a, b, c, e, and h together.
 - When a node in the batch completes the job, it’s removed from the batch and another node is added and starts executing the job.
 - This continues until all nodes in the group have completed the job.
 
Note
The order that nodes are added to a batch is not necessarily sequential. batching- Work starts on a batch of nodes whose size is determined by 
batchSize. The next batch of nodes doesn’t begin until all nodes in the prior batch have completed execution or timed out.For example:
- There’s a batch size of 5 for the following node distribution group: a, b, c, d, e, f, g, h, i, j, k.
 - Job runs are performed first on any five nodes, for example a, b, c, e, and h together.
 - After all five nodes complete, then any other five nodes within the group execute together. For example: d, f, g, i, and k.
 - The job run starts on the last node (in this case, j) after the completion of the second batch.
 
Note
The order that nodes are added to a batch is not necessarily sequential. 
 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 
SuccessCriteriato evaluate astrue.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:
filtersavedFiltersavedListnodes
Depending on the value, you must also set the following:
- if set to 
filter, add a filter infilter - if set to 
savedFilter, add a filter ID infilterId - if set to 
savedList, provide a list ID inlistId - if set to 
nodes, provide a list of node IDs innodeIdentifiers. 
Type: enum
 target.groups.[].filter- An adhoc filter.
Required if 
nodeListTypeis set tofilter.It must comply with the
Node.FilterExecschema 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 
nodeListTypeis set tosavedFilter.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 
nodeListTypeis set tosavedList.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.
The order of nodes in
nodeIdentifiersdoesn’t dictate the order of execution within a group. Seetarget.groups.[].distributionMethodfor more details.Required if
nodeListTypeis set tonodes.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"
          ]
      }
  ]
},
...
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
[target]
executionType = "sequential"
[[target.groups]]
timeoutSeconds = 240
distributionMethod = "batching"
nodeListType = "nodes"
nodeIdentifiers = [ "5a222a24-ed1d-42dc-83d1-770c3ad7d09d" ]
  [target.groups.batchSize]
  type = "number"
  value = 1
  [[target.groups.successCriteria]]
  status = "success"
    [target.groups.successCriteria.numRuns]
    type = "percent"
    value = 100
[[target.groups]]
timeoutSeconds = 120
distributionMethod = "batching"
nodeListType = "nodes"
nodeIdentifiers = [ "6253d757-362a-487c-9cf3-9311f8bad0b7" ]
  [target.groups.batchSize]
  type = "number"
  value = 1
  [[target.groups.successCriteria]]
  status = "success"
    [target.groups.successCriteria.numRuns]
    type = "percent"
    value = 100
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.
You can use
expectedInputsto make outputs from any step be available for usage in any subsequent step. For example:- Step one has the output variable 
ABC. - Step two has the output variable 
DEF. - Step three can include 
ABCin the step by adding it toexpectedInputs. - Step four can include 
ABCandDEFin the step by adding them toexpectedInputs. 
The value stored in the output variables can be updated by any step and this will be reflected in subsequent steps. In the above example, if step three sets a new value in
ABCas output variable, then step four will get this new value forABCand not the original value from step one.Type: object (string, ExpectedStepInput)
Example:
"expectedInputs": { "<INPUT_NAME>": { "default": "<STRING>", "required": <BOOLEAN>, "sensitive": <BOOLEAN> } }, - Step one has the output variable 
 actions.steps.[].expectedInputs.[].default- A default value used if no value is returned from an input.
Type: string
Example: “value1”
 actions.steps.[].expectedInputs.[].required- Whether the input 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 ofinputsin 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 
sourceTypeisartifact, thensourcemust be a path, for examplesource="/tmp/path/file.log". - If 
sourceTypeisexitCode, then thesourceproperty isn’t used. - If 
sourceTypeisfile, thensourcemust be a path, such assource="/tmp/path/file.txt". - If 
sourceTypeisoutput, thensourcemust be the output name, eitherstdoutorstderr. 
Type: string
 - If 
 actions.steps.[].outputFieldRules.extractMethod- The method to extract the output:
regex: a regular expression to run againstsourceto extract the field value.jsonPath: parsesourceas JSON and extract the value using the path specified inexpression.content: include the full content ofsourcebased onsourceType.- If 
sourceTypeisartifact, thenextractMethodyields the full content of the artifact. - If 
sourceTypeisexitCode, thenextractMethodis treated as content and yields the exit code itself. - If 
sourceTypeisfile, thenextractMethodyields the full content of the file. - If 
sourceTypeisoutput, thenextractMethodyields the full output (stdout or stderr based onsource). 
Note that
contentis intended for small payloads (measured in tens of bytes or less) since it’s used for comparison purposes in subsequent steps.- If 
 
Type: enum
Possible values:
regEx,jsonPath,content actions.steps.[].outputFieldRules.expression- The expression to apply to 
sourceusingextractMethodto extract the value.If
extractMethodis set to:regEx, define a regular expression to extract the value.jsonPath, define a JSON path to the value.content, then the full content ofsourceis based on thesourceType:- If 
sourceTypeisartifact, thencontentincludes the full content of the artifact. - If 
sourceTypeisexitCode, thencontentis the exit code value of the step. - If 
sourceTypeisfile, thencontentis the full content of the file. - If 
sourceTypeisoutput, thencontentincludes everything emitted from the standard output or standard error output stream. 
- If 
 
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 
failureBehaviorproperty.For example, set the number of retries to stop a background process to
5because 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:
retryThenFailRetry according to retry rules. If the step is still failing after retries are exhausted or
retryCountis 0, fail this step and abort the job run.retryThenIgnoreRetry according to retry rules. If the step is still failing after retries are exhausted or
retryCountis 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 
retryCounttimes.Type: object
 actions.steps.[].failureBehavior.retryBackoffStrategy.type- The retry backoff strategy type.
Allowed values are as follows:
nonefor no backoff - retry after the duration specified bydelaySecondswithout modificationlinearfor backoff, such as (delaySeconds*attemptNumber)exponentialdelaySeconds^attemptNumberpolynomialattemptNumber^x, wherexis provided as the first element ofarguments. Each attempt uses the next number inargumentsasx.
Type: enum
Possible values:
none,linear,exponential,polynomialDefault 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 try/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 
0for ‘all’.Type: integer
Default value:
0Example:
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.0Minimum: 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 
0means 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 tofalse, 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,eqis 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:
eqgtgteltltematchesstartsWithendsWithcontains.
 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
trueif the value of input ‘inputOne’ equals the value of ‘inputZero’. To compare the literal$at the start of a value, use$$. For example,eq$$value1evaluates true ifinput == '$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": [
              ]
          }
      ]
  },
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: []
[actions]
accessMode = "agent"
  [[actions.steps]]
  name = "sleep"
  stepNumber = 1
  inputs = { }
  expectedInputs = { }
  OutputFieldRules = { }
  retryCount = 2
  limits = { }
  conditions = [ ]
    [actions.steps.interpreter]
    name = "chef-platform/shell-interpreter"
    [actions.steps.command]
    linux = [ "sleep 10" ]
    [actions.steps.failureBehavior]
    action = "retryThenFail"
      [actions.steps.failureBehavior.retryBackoffStrategy]
      type = "none"
      delaySeconds = 0
      arguments = [ 1, 3, 5 ]
Empty job templates
The following is an empty job template—you can use it to define a new Courier job.
Some of the parameters in these templates conflict with each other and can’t be included in the same job.
The following empty job template defines a simple job with the fewest job details:
{
  "name": "<STRING>",
  "description": "<STRING>",
  "exceptionRules":[],
  "scheduleRule":"<STRING>",
  "target": {
    "executionType": "<STRING>",
    "groups":[
      {
        "timeoutSeconds": <INTEGER>,
        "batchSize": {
            "type":"<STRING>",
            "value": <INTEGER>
        },
        "distributionMethod":"<ENUM>",
        "successCriteria": [{"status":"<ENUM>", "numRuns":{"type":"<ENUM>", "value":<INTEGER>}}],
        "nodeListType": "<ENUM>",
        "listId": "<STRING>",
        "filterId": <INTEGER>,
        "nodeIdentifiers":["<STRING>"],
        "filter": {}
      }
    ]
  },
  "actions": {
    "accessMode":"agent",
    "steps":
    [
      {
        "name": "<STRING>",
        "interpreter": {
          "name": "<STRING>",
          "skill": {
            "minVersion": "<STRING>"
          }
        },
        "command": {},
        "inputs":{},
        "expectedInputs":{},
        "outputFieldRules":{},
        "retryCount": <INTEGER>,
        "limits":{},
        "conditions":[],
        "failureBehavior":{
            "action":"retryThenFail",
            "retryBackoffStrategy":{"name":"none", "delaySeconds":<INTEGER>}
        }
      }
    ]
  }
}The following empty job template has more job details:
{
  "name":"<STRING>",
  "description": "<STRING>",
  "scheduleRule": "immediate|RRule",
  "exceptionRules": [],
  "target": {
    "executionType": "sequential"|"parallel",
    "groups":[
      {
        "timeoutSeconds": <INTEGER>,
        "batchSize": {
          "type": "number"|"percent",
          "value": <INTEGER>
        },
        "distributionMethod": "rolling"|"batching",
        "successCriteria": [
          {
            "numRuns": {
              "type": "number"|"percent",
              "value": <INTEGER>
            },
            "status": "success"|"failure"
          }
        ],
        "nodeListType": "filter"|"savedFilter"|"savedList"|"nodes",
        "listId": "<STRING>",
        "filterId": <INTEGER>,
        "nodeIdentifiers":["<STRING>"],
        "filter": {}
      }
    ]
  },
  "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": "artifact"|"exitCode"|"file"|"output",
          "source": "<STRING>",
          "extractMethod": "regex"|"jsonPath"|"content",
          "expression": "<STRING>",
          "required": <BOOLEAN>,
          "sensitive": <BOOLEAN>
        },
        "retryCount": <INTEGER>,
        "failureBehavior": {
          "action": "retryThenFail"|"retryThenIgnore",
          "retryBackoffStrategy": {
            "name": "none"|"linear"|"exponential"|"polynomial",
            "delaySeconds": <INTEGER>,
            "arguments": []
          }
        },
        "limits": {
          "cores": <INTEGER>,
          "cpu": <FLOAT>,
          "timeoutSeconds": <INTEGER>,
        },
        "conditions": [
          {
            "inputName": "<STRING>",
            "negate": <BOOLEAN>,
            "operator": "eq"|"gt"|"gte"|"lt"|"lte"|"matches"|"startsWith"|"endsWith"|"contains",
            "value": "<STRING>"
          }
        ]
      }
    ]
  }
}
Examples
Use the following examples to define basic jobs. You can find additional examples in the chef/samples repository.
A simple shell command
This Courier job template uses the Shell interpreter to make the shell sleep for 10 seconds.
{
  "name": "a simple job to perform one action",
  "description": "Perform a simple shell command on specific nodes to understand the fundamentals of Courier jobs",
  "scheduleRule": "immediate",
  "exceptionRules": [],
  "target": {
    "executionType": "sequential",
    "groups":[
      {
        "timeoutSeconds": 240,
        "batchSize": {},
        "distributionMethod": "batching",
        "successCriteria": [
          {
            "numRuns": { "type": "percent", "value": 100 },
            "status": "success"
          }
        ],
        "nodeListType":"nodes",
        "nodeIdentifiers":[
          "--NODE1--"
        ]
      },
      {
        "timeoutSeconds": 120,
        "batchSize": {
          "type": "number",
          "value": 1
        },
        "distributionMethod":"batching",
        "successCriteria": [{ "numRuns": { "type": "percent", "value": 100 }, "status": "success" }],
        "nodeListType":"nodes",
        "nodeIdentifiers":[
          "--NODE2--",
          "--NODE3--"
        ]
      }
    ]
  },
  "actions": {
    "accessMode": "agent",
    "steps":
    [
      {
        "name": "step to sleep",
        "interpreter": {
          "skill": {
            "minVersion": "1.0.0"
          },
          "name": "chef-platform/shell-interpreter"
        },
        "command": {
          "linux": [
            "sleep 10"
          ],
          "windows": [
            "timeout 10"
          ]
        },
        "inputs": {},
        "expectedInputs": { },
        "outputFieldRules": {},
        "retryCount": 2,
        "failureBehavior": {
          "action": "retryThenFail",
          "retryBackoffStrategy": {
            "type": "linear",
            "delaySeconds": 1,
            "arguments": [1,3,5]
          }
        },
        "limits": {},
        "conditions": []
      }
    ]
  }
}
actions:
  accessMode: agent
  steps:
  - command:
      linux:
      - sleep 10
      windows:
      - timeout 10
    conditions: []
    expectedInputs: {}
    failureBehavior:
      action: retryThenFail
      retryBackoffStrategy:
        arguments:
        - 1
        - 3
        - 5
        delaySeconds: 1
        type: linear
    inputs: {}
    interpreter:
      name: chef-platform/shell-interpreter
      skill:
        minVersion: 1.0.0
    limits: {}
    name: step to sleep
    outputFieldRules: {}
    retryCount: 2
description: Perform a simple shell command on specific nodes to understand the fundamentals
  of Courier jobs
exceptionRules: []
name: a simple job to perform one action
scheduleRule: immediate
target:
  executionType: sequential
  groups:
  - batchSize: {}
    distributionMethod: batching
    nodeIdentifiers:
    - --NODE1--
    nodeListType: nodes
    successCriteria:
    - numRuns:
        type: percent
        value: 100
      status: success
    timeoutSeconds: 240
  - batchSize:
      type: number
      value: 1
    distributionMethod: batching
    nodeIdentifiers:
    - --NODE2--
    - --NODE3--
    nodeListType: nodes
    successCriteria:
    - numRuns:
        type: percent
        value: 100
      status: success
    timeoutSeconds: 120
description = 'Perform a simple shell command on specific nodes to understand the fundamentals of Courier jobs'
exceptionRules = []
name = 'a simple job to perform one action'
scheduleRule = 'immediate'
[actions]
  accessMode = 'agent'
  [[actions.steps]]
    conditions = []
    name = 'step to sleep'
    retryCount = 2.0
    [actions.steps.command]
      linux = ['sleep 10']
      windows = ['timeout 10']
    [actions.steps.expectedInputs]
    [actions.steps.failureBehavior]
      action = 'retryThenFail'
      [actions.steps.failureBehavior.retryBackoffStrategy]
        arguments = [1.0, 3.0, 5.0]
        delaySeconds = 1.0
        type = 'linear'
    [actions.steps.inputs]
    [actions.steps.interpreter]
      name = 'chef-platform/shell-interpreter'
      [actions.steps.interpreter.skill]
        minVersion = '1.0.0'
    [actions.steps.limits]
    [actions.steps.outputFieldRules]
[target]
  executionType = 'sequential'
  [[target.groups]]
    distributionMethod = 'batching'
    nodeIdentifiers = ['--NODE1--']
    nodeListType = 'nodes'
    timeoutSeconds = 240.0
    [target.groups.batchSize]
    [[target.groups.successCriteria]]
      status = 'success'
      [target.groups.successCriteria.numRuns]
        type = 'percent'
        value = 100.0
  [[target.groups]]
    distributionMethod = 'batching'
    nodeIdentifiers = ['--NODE2--', '--NODE3--']
    nodeListType = 'nodes'
    timeoutSeconds = 120.0
    [target.groups.batchSize]
      type = 'number'
      value = 1.0
    [[target.groups.successCriteria]]
      status = 'success'
      [target.groups.successCriteria.numRuns]
        type = 'percent'
        value = 100.0
Run the Chef Infra Client interpreter
This job template uses the Chef Infra Client interpreter to execute an Infra Client run in local mode. For more information see the Chef Infra Client interpreter documentation.
{
  "name": "infra client local run",
  "description": "Perform simple Chef Infra Client run from local using courier jobs",
  "scheduleRule": "immediate",
  "exceptionRules": [],
  "target": {
    "executionType": "sequential",
    "groups":[
      {
        "timeoutSeconds": 240,
        "batchSize": {},
        "distributionMethod": "batching",
        "successCriteria": [
          {
            "numRuns": { "type": "percent", "value": 100 },
            "status": "success"
          }
        ],
        "nodeListType":"nodes",
        "nodeIdentifiers":[
          "--NODE1--"
        ]
      }
    ]
  },
  "actions": {
    "accessMode": "agent",
    "steps":
    [
      {
        "name": "step to pem keys",
        "interpreter": {
          "skill": {
            "minVersion": "1.0.0",
            "maxVersion": "19"
          },
          "name": "chef-platform/chef-client-interpreter"
        },
        "command": {
          "exec": "run",
          "args": {
            "mode": "local",
            "source": "/home/ec2-user/chef-repo/cookbooks",
            "runlist": "nginx::default"
          }
        },
        "inputs": {},
        "expectedInputs": { },
        "outputFieldRules": {},
        "retryCount": 2,
        "failureBehavior": {
          "action": "retryThenFail",
          "retryBackoffStrategy": {
            "type": "linear",
            "delaySeconds": 1,
            "arguments": [1,3,5]
          }
        },
        "limits": {},
        "conditions": []
      }
    ]
  }
}actions:
  accessMode: agent
  steps:
  - command:
      args:
        mode: local
        runlist: nginx::default
        source: /home/ec2-user/chef-repo/cookbooks
      exec: run
    conditions: []
    expectedInputs: {}
    failureBehavior:
      action: retryThenFail
      retryBackoffStrategy:
        arguments:
        - 1
        - 3
        - 5
        delaySeconds: 1
        type: linear
    inputs: {}
    interpreter:
      name: chef-platform/chef-client-interpreter
      skill:
        maxVersion: "19"
        minVersion: 1.0.0
    limits: {}
    name: step to pem keys
    outputFieldRules: {}
    retryCount: 2
description: Perform simple Chef Infra Client run from local using courier jobs
exceptionRules: []
name: infra client local run
scheduleRule: immediate
target:
  executionType: sequential
  groups:
  - batchSize: {}
    distributionMethod: batching
    nodeIdentifiers:
    - --NODE1--
    nodeListType: nodes
    successCriteria:
    - numRuns:
        type: percent
        value: 100
      status: success
    timeoutSeconds: 240
description = 'Perform simple Chef Infra Client run from local using courier jobs'
exceptionRules = []
name = 'infra client local run'
scheduleRule = 'immediate'
[actions]
  accessMode = 'agent'
  [[actions.steps]]
    conditions = []
    name = 'step to pem keys'
    retryCount = 2.0
    [actions.steps.command]
      exec = 'run'
      [actions.steps.command.args]
        mode = 'local'
        runlist = 'nginx::default'
        source = '/home/ec2-user/chef-repo/cookbooks'
    [actions.steps.expectedInputs]
    [actions.steps.failureBehavior]
      action = 'retryThenFail'
      [actions.steps.failureBehavior.retryBackoffStrategy]
        arguments = [1.0, 3.0, 5.0]
        delaySeconds = 1.0
        type = 'linear'
    [actions.steps.inputs]
    [actions.steps.interpreter]
      name = 'chef-platform/chef-client-interpreter'
      [actions.steps.interpreter.skill]
        maxVersion = '19'
        minVersion = '1.0.0'
    [actions.steps.limits]
    [actions.steps.outputFieldRules]
[target]
  executionType = 'sequential'
  [[target.groups]]
    distributionMethod = 'batching'
    nodeIdentifiers = ['--NODE1--']
    nodeListType = 'nodes'
    timeoutSeconds = 240.0
    [target.groups.batchSize]
    [[target.groups.successCriteria]]
      status = 'success'
      [target.groups.successCriteria.numRuns]
        type = 'percent'
        value = 100.0
Run a Chef InSpec scan
This job template runs a Chef InSpec scan on a node.
{
  "name":"Inspec scan",
  "description":"Example to showcase running an Inspec exec on Linux",
  "scheduleRule": "immediate",
  "exceptionRules": [],
  "target": {
    "executionType": "sequential",
    "groups": [
      {
        "timeoutSeconds": 120,
        "batchSize": {},
        "distributionMethod": "batching",
        "successCriteria": [
          {
            "numRuns": {
              "type": "percent",
              "value": 100
            },
            "status": "success"
          }
        ],
        "nodeListType": "nodes",
        "nodeIdentifiers": [
          "--NODE1--"
        ]
      }
    ]
  },
  "actions": {
    "accessMode": "agent",
    "steps": [
      {
        "minVersion": "1.0.0",
        "maxVersion": "16.0.0",
        "name": "inspec",
        "interpreter": {
          "skill": {
            "minVersion": "1.0.0",
            "maxVersion": "16.0.0"
          },
          "name": "chef-platform/inspec-interpreter"
        },
        "command": {
           "exec":"scan",
           "args": {
           "path":"https://github.com/akshayparvatikar29/cert-compliance"
            }
        },
        "inputs": {},
        "expectedInputs": {},
        "outputFieldRules": {
           "INSPEC_VALUE": {
                 "source": "stdout",
                 "sourceType": "output",
                 "extractMethod": "regEx",
                 "expression": "0 successful",
                 "required": true,
                 "sensitive": false
           }
        },
        "retryCount": 2,
        "failureBehavior": {
          "action": "retryThenFail",
          "retryBackoffStrategy": {
            "type": "none",
            "delaySeconds": 1,
            "arguments": [1,3,5]
          }
        },
        "limits": {},
        "conditions": [],
        "name": "capture inspec value into variable"
      },
      {
        "interpreter": {
        "skill": {
        "minVersion": "1.0.0"
          },
        "name": "chef-platform/shell-interpreter"
           },
        "inputs": {},
            "expectedInputs": {
                 "INSPEC_VALUE": {
                        "type": "string",
                        "sensitive": false,
                        "required": true,
                        "default": ""
                    }
                },
                "outputFieldRules": {},
                "conditions": [
                    {
                        "inputName": "INSPEC_VALUE",
                        "operator": "eq",
                        "value": "0 successful"
                    }
                ],
                "command": {"linux": [
                    "sleep 10"
                ]},
                "retryCount": 2,
                "failureBehavior": {
                    "action": "retryThenFail",
                    "retryBackoffStrategy": {
                        "type": "linear",
                        "delaySeconds": 1,
                        "arguments": []
                    }
                },
                "limits": {},
                "name": "executing command with inspec variable"
      }
    ]
  }
}actions:
  accessMode: agent
  steps:
  - command:
      args:
        path: https://github.com/akshayparvatikar29/cert-compliance
      exec: scan
    conditions: []
    expectedInputs: {}
    failureBehavior:
      action: retryThenFail
      retryBackoffStrategy:
        arguments:
        - 1
        - 3
        - 5
        delaySeconds: 1
        type: none
    inputs: {}
    interpreter:
      name: chef-platform/inspec-interpreter
      skill:
        maxVersion: 16.0.0
        minVersion: 1.0.0
    limits: {}
    maxVersion: 16.0.0
    minVersion: 1.0.0
    name: capture inspec value into variable
    outputFieldRules:
      INSPEC_VALUE:
        expression: 0 successful
        extractMethod: regEx
        required: true
        sensitive: false
        source: stdout
        sourceType: output
    retryCount: 2
  - command:
      linux:
      - sleep 10
    conditions:
    - inputName: INSPEC_VALUE
      operator: eq
      value: 0 successful
    expectedInputs:
      INSPEC_VALUE:
        default: ""
        required: true
        sensitive: false
        type: string
    failureBehavior:
      action: retryThenFail
      retryBackoffStrategy:
        arguments: []
        delaySeconds: 1
        type: linear
    inputs: {}
    interpreter:
      name: chef-platform/shell-interpreter
      skill:
        minVersion: 1.0.0
    limits: {}
    name: executing command with inspec variable
    outputFieldRules: {}
    retryCount: 2
description: Example to showcase running an Inspec exec on Linux
exceptionRules: []
name: Inspec scan
scheduleRule: immediate
target:
  executionType: sequential
  groups:
  - batchSize: {}
    distributionMethod: batching
    nodeIdentifiers:
    - --NODE1--
    nodeListType: nodes
    successCriteria:
    - numRuns:
        type: percent
        value: 100
      status: success
    timeoutSeconds: 120
description = 'Example to showcase running an Inspec exec on Linux'
exceptionRules = []
name = 'Inspec scan'
scheduleRule = 'immediate'
[actions]
  accessMode = 'agent'
  [[actions.steps]]
    conditions = []
    maxVersion = '16.0.0'
    minVersion = '1.0.0'
    name = 'capture inspec value into variable'
    retryCount = 2.0
    [actions.steps.command]
      exec = 'scan'
      [actions.steps.command.args]
        path = 'https://github.com/akshayparvatikar29/cert-compliance'
    [actions.steps.expectedInputs]
    [actions.steps.failureBehavior]
      action = 'retryThenFail'
      [actions.steps.failureBehavior.retryBackoffStrategy]
        arguments = [1.0, 3.0, 5.0]
        delaySeconds = 1.0
        type = 'none'
    [actions.steps.inputs]
    [actions.steps.interpreter]
      name = 'chef-platform/inspec-interpreter'
      [actions.steps.interpreter.skill]
        maxVersion = '16.0.0'
        minVersion = '1.0.0'
    [actions.steps.limits]
    [actions.steps.outputFieldRules]
      [actions.steps.outputFieldRules.INSPEC_VALUE]
        expression = '0 successful'
        extractMethod = 'regEx'
        required = true
        sensitive = false
        source = 'stdout'
        sourceType = 'output'
  [[actions.steps]]
    name = 'executing command with inspec variable'
    retryCount = 2.0
    [actions.steps.command]
      linux = ['sleep 10']
    [[actions.steps.conditions]]
      inputName = 'INSPEC_VALUE'
      operator = 'eq'
      value = '0 successful'
    [actions.steps.expectedInputs]
      [actions.steps.expectedInputs.INSPEC_VALUE]
        default = ''
        required = true
        sensitive = false
        type = 'string'
    [actions.steps.failureBehavior]
      action = 'retryThenFail'
      [actions.steps.failureBehavior.retryBackoffStrategy]
        arguments = []
        delaySeconds = 1.0
        type = 'linear'
    [actions.steps.inputs]
    [actions.steps.interpreter]
      name = 'chef-platform/shell-interpreter'
      [actions.steps.interpreter.skill]
        minVersion = '1.0.0'
    [actions.steps.limits]
    [actions.steps.outputFieldRules]
[target]
  executionType = 'sequential'
  [[target.groups]]
    distributionMethod = 'batching'
    nodeIdentifiers = ['--NODE1--']
    nodeListType = 'nodes'
    timeoutSeconds = 120.0
    [target.groups.batchSize]
    [[target.groups.successCriteria]]
      status = 'success'
      [target.groups.successCriteria.numRuns]
        type = 'percent'
        value = 100.0
Target batches of Linux nodes
This job template runs a shell command on batches of Linux nodes.
{
    "name":"job direct query",
    "description": "Demonstrating a simple job to be performed against nodes resolved for an adhoc search query for Linux in batches of 5 nodes",
    "scheduleRule": "immediate",
    "exceptionRules":[],
    "target": {
        "executionType": "sequential",
        "groups":[
            {
                "timeoutSeconds": 60,
                "batchSize": {
                    "type": "number",
                    "value": 5
                },
                "distributionMethod":"batching",
                "successCriteria": [{ "numRuns": { "type": "percent", "value": 100 }, "status": "success" }],
                "nodeListType":"filter",
                "filter":{ "constraints": { "attributes": [ { "name" : "kernel_name", "operator" : "=", "value" : ["Linux"] }  ]  }  }
            }
        ]
    },
    "actions": {
        "accessMode": "agent",
        "steps": 
        [
            {
                "name": "step to sleep",
                "interpreter": {
                  "skill": {
                    "minVersion": "1.0.0"
                  },
                  "name": "chef-platform/shell-interpreter"
                },
                "command": {
                  "linux": [
                    "sleep 10"
                  ],
                  "windows": [
                    "timeout 10"
                  ]
                },
                "inputs": {},
                "expectedInputs": { },
                "outputFieldRules": {},
                "retryCount": 2,
                "failureBehavior": {
                  "action": "retryThenFail",
                  "retryBackoffStrategy": {
                    "type": "linear",
                    "delaySeconds": 1,
                    "arguments": [1,3,5]
                  }
                },
                "limits": {},
                "conditions": []
            }
        ]
    }
}
actions:
  accessMode: agent
  steps:
  - command:
      linux:
      - sleep 10
      windows:
      - timeout 10
    conditions: []
    expectedInputs: {}
    failureBehavior:
      action: retryThenFail
      retryBackoffStrategy:
        arguments:
        - 1
        - 3
        - 5
        delaySeconds: 1
        type: linear
    inputs: {}
    interpreter:
      name: chef-platform/shell-interpreter
      skill:
        minVersion: 1.0.0
    limits: {}
    name: step to sleep
    outputFieldRules: {}
    retryCount: 2
description: Demonstrating a simple job to be performed against nodes resolved for
  an adhoc search query for Linux in batches of 5 nodes
exceptionRules: []
name: job direct query
scheduleRule: immediate
target:
  executionType: sequential
  groups:
  - batchSize:
      type: number
      value: 5
    distributionMethod: batching
    filter:
      constraints:
        attributes:
        - name: kernel_name
          operator: =
          value:
          - Linux
    nodeListType: filter
    successCriteria:
    - numRuns:
        type: percent
        value: 100
      status: success
    timeoutSeconds: 60
description = 'Demonstrating a simple job to be performed against nodes resolved for an adhoc search query for Linux in batches of 5 nodes'
exceptionRules = []
name = 'job direct query'
scheduleRule = 'immediate'
[actions]
  accessMode = 'agent'
  [[actions.steps]]
    conditions = []
    name = 'step to sleep'
    retryCount = 2.0
    [actions.steps.command]
      linux = ['sleep 10']
      windows = ['timeout 10']
    [actions.steps.expectedInputs]
    [actions.steps.failureBehavior]
      action = 'retryThenFail'
      [actions.steps.failureBehavior.retryBackoffStrategy]
        arguments = [1.0, 3.0, 5.0]
        delaySeconds = 1.0
        type = 'linear'
    [actions.steps.inputs]
    [actions.steps.interpreter]
      name = 'chef-platform/shell-interpreter'
      [actions.steps.interpreter.skill]
        minVersion = '1.0.0'
    [actions.steps.limits]
    [actions.steps.outputFieldRules]
[target]
  executionType = 'sequential'
  [[target.groups]]
    distributionMethod = 'batching'
    nodeListType = 'filter'
    timeoutSeconds = 60.0
    [target.groups.batchSize]
      type = 'number'
      value = 5.0
    [target.groups.filter]
      [target.groups.filter.constraints]
        [[target.groups.filter.constraints.attributes]]
          name = 'kernel_name'
          operator = '='
          value = ['Linux']
    [[target.groups.successCriteria]]
      status = 'success'
      [target.groups.successCriteria.numRuns]
        type = 'percent'
        value = 100.0
Reboot nodes
This job template uses two actions to write a file and then reboot nodes.
{
    "name": "Sample reboot",
    "description": "To demonstrate a reboot action as a part of a simple courier job on a node",
    "scheduleRule": "immediate",
    "exceptionRules":[],
    "target": {
      "executionType": "sequential",
      "groups":[
        {
          "timeoutSeconds": 240,
          "batchSize": {
           "type": "number",
           "value": 1
            },
          "distributionMethod": "batching",
          "successCriteria": [
            {
              "numRuns": { "type": "percent", "value": 100 },
              "status": "success"
            }
          ],
          "nodeListType":"nodes",
          "nodeIdentifiers":[
            "--NODE1--"
          ]
        }
      ]
    },
    "actions": {
      "accessMode": "agent",
      "steps":
      [
        {
          "name": "step to perform file write before a reboot",
          "interpreter": {
          "skill": {
              "minVersion": "1.0.0"
            },
            "name": "chef-platform/shell-interpreter"
          },
          "command": {
            "linux": [
              "echo 'before restart..' > /home/ec2-user/before-restart.txt"
            ],
              "windows": [
              "echo 'before restart..' > C:\\Users\\Administrator\\before-restart.txt"
            ]
          },
          "inputs": {},
          "expectedInputs": { },
          "outputFieldRules": {},
          "retryCount": 2,
          "failureBehavior": {
            "action": "retryThenFail",
            "retryBackoffStrategy": {
              "type": "none",
              "delaySeconds": 1,
              "arguments": [1,3,5]
            }
          },
          "limits": {},
          "conditions": []
        },
        {
          "name": "step to perform reboot",
          "interpreter": {
          "skill": {
              "minVersion": "0.0.0",
              "maxVersion":"2.0.0"
            },
            "name": "chef-platform/restart-interpreter"
          },
          "command": {
            "exec":"machine_reboot"
          },
          "inputs": {},
          "expectedInputs": { },
          "outputFieldRules": {},
          "retryCount": 2,
          "failureBehavior": {
            "action": "retryThenFail",
            "retryBackoffStrategy": {
              "type": "linear",
              "delaySeconds": 1,
              "arguments": [1,3,5]
            }
          },
          "limits": {},
          "conditions": []
        },
        {
          "name": "step to perform file write after reboot",
          "interpreter": {
          "skill": {
              "minVersion": "1.0.0"
            },
            "name": "chef-platform/shell-interpreter"
          },
          "command": {
            "linux": [
              "echo 'after restart..' > /home/ec2-user/after-restart.txt"
            ],
              "windows": [
              "echo 'after restart..' > C:\\Users\\Administrator\\after-restart.txt"
            ]
          },
          "inputs": {},
          "expectedInputs": { },
          "outputFieldRules": {},
          "retryCount": 2,
          "failureBehavior": {
            "action": "retryThenFail",
            "retryBackoffStrategy": {
              "type": "linear",
              "delaySeconds": 1,
              "arguments": [1,3,5]
            }
          },
          "limits": {},
          "conditions": []
        }
      ]
    }
  }actions:
  accessMode: agent
  steps:
  - command:
      linux:
      - echo 'before restart..' > /home/ec2-user/before-restart.txt
      windows:
      - echo 'before restart..' > C:\Users\Administrator\before-restart.txt
    conditions: []
    expectedInputs: {}
    failureBehavior:
      action: retryThenFail
      retryBackoffStrategy:
        arguments:
        - 1
        - 3
        - 5
        delaySeconds: 1
        type: none
    inputs: {}
    interpreter:
      name: chef-platform/shell-interpreter
      skill:
        minVersion: 1.0.0
    limits: {}
    name: step to perform file write before a reboot
    outputFieldRules: {}
    retryCount: 2
  - command:
      exec: machine_reboot
    conditions: []
    expectedInputs: {}
    failureBehavior:
      action: retryThenFail
      retryBackoffStrategy:
        arguments:
        - 1
        - 3
        - 5
        delaySeconds: 1
        type: linear
    inputs: {}
    interpreter:
      name: chef-platform/restart-interpreter
      skill:
        maxVersion: 2.0.0
        minVersion: 0.0.0
    limits: {}
    name: step to perform reboot
    outputFieldRules: {}
    retryCount: 2
  - command:
      linux:
      - echo 'after restart..' > /home/ec2-user/after-restart.txt
      windows:
      - echo 'after restart..' > C:\Users\Administrator\after-restart.txt
    conditions: []
    expectedInputs: {}
    failureBehavior:
      action: retryThenFail
      retryBackoffStrategy:
        arguments:
        - 1
        - 3
        - 5
        delaySeconds: 1
        type: linear
    inputs: {}
    interpreter:
      name: chef-platform/shell-interpreter
      skill:
        minVersion: 1.0.0
    limits: {}
    name: step to perform file write after reboot
    outputFieldRules: {}
    retryCount: 2
description: To demonstrate a reboot action as a part of a simple courier job on a
  node
exceptionRules: []
name: Sample reboot
scheduleRule: immediate
target:
  executionType: sequential
  groups:
  - batchSize:
      type: number
      value: 1
    distributionMethod: batching
    nodeIdentifiers:
    - --NODE1--
    nodeListType: nodes
    successCriteria:
    - numRuns:
        type: percent
        value: 100
      status: success
    timeoutSeconds: 240
description = 'To demonstrate a reboot action as a part of a simple courier job on a node'
exceptionRules = []
name = 'Sample reboot'
scheduleRule = 'immediate'
[actions]
  accessMode = 'agent'
  [[actions.steps]]
    conditions = []
    name = 'step to perform file write before a reboot'
    retryCount = 2.0
    [actions.steps.command]
      linux = ["echo 'before restart..' > /home/ec2-user/before-restart.txt"]
      windows = ["echo 'before restart..' > C:\\Users\\Administrator\\before-restart.txt"]
    [actions.steps.expectedInputs]
    [actions.steps.failureBehavior]
      action = 'retryThenFail'
      [actions.steps.failureBehavior.retryBackoffStrategy]
        arguments = [1.0, 3.0, 5.0]
        delaySeconds = 1.0
        type = 'none'
    [actions.steps.inputs]
    [actions.steps.interpreter]
      name = 'chef-platform/shell-interpreter'
      [actions.steps.interpreter.skill]
        minVersion = '1.0.0'
    [actions.steps.limits]
    [actions.steps.outputFieldRules]
  [[actions.steps]]
    conditions = []
    name = 'step to perform reboot'
    retryCount = 2.0
    [actions.steps.command]
      exec = 'machine_reboot'
    [actions.steps.expectedInputs]
    [actions.steps.failureBehavior]
      action = 'retryThenFail'
      [actions.steps.failureBehavior.retryBackoffStrategy]
        arguments = [1.0, 3.0, 5.0]
        delaySeconds = 1.0
        type = 'linear'
    [actions.steps.inputs]
    [actions.steps.interpreter]
      name = 'chef-platform/restart-interpreter'
      [actions.steps.interpreter.skill]
        maxVersion = '2.0.0'
        minVersion = '0.0.0'
    [actions.steps.limits]
    [actions.steps.outputFieldRules]
  [[actions.steps]]
    conditions = []
    name = 'step to perform file write after reboot'
    retryCount = 2.0
    [actions.steps.command]
      linux = ["echo 'after restart..' > /home/ec2-user/after-restart.txt"]
      windows = ["echo 'after restart..' > C:\\Users\\Administrator\\after-restart.txt"]
    [actions.steps.expectedInputs]
    [actions.steps.failureBehavior]
      action = 'retryThenFail'
      [actions.steps.failureBehavior.retryBackoffStrategy]
        arguments = [1.0, 3.0, 5.0]
        delaySeconds = 1.0
        type = 'linear'
    [actions.steps.inputs]
    [actions.steps.interpreter]
      name = 'chef-platform/shell-interpreter'
      [actions.steps.interpreter.skill]
        minVersion = '1.0.0'
    [actions.steps.limits]
    [actions.steps.outputFieldRules]
[target]
  executionType = 'sequential'
  [[target.groups]]
    distributionMethod = 'batching'
    nodeIdentifiers = ['--NODE1--']
    nodeListType = 'nodes'
    timeoutSeconds = 240.0
    [target.groups.batchSize]
      type = 'number'
      value = 1.0
    [[target.groups.successCriteria]]
      status = 'success'
      [target.groups.successCriteria.numRuns]
        type = 'percent'
        value = 100.0
Filter nodes
This job template runs a shell command on nodes returned by a saved node filter.
{
    "name":"job saved filter",
    "description": "demonstrating running a job using a saved filter",
    "scheduleRule": "immediate",
    "exceptionRules":[],
    "target": {
        "executionType": "sequential",
        "groups":[
            {
                "timeoutSeconds": 300,
                "batchSize": {
                    "type": "number",
                    "value": 5
                },
                "distributionMethod":"batching",
                "successCriteria": [{ "numRuns": { "type": "percent", "value": 100 }, "status": "success" }],
                "nodeListType":"savedFilter",
	            "filterId": "--FILTER ID--"
            }
        ]
    },
    "actions": {
        "accessMode": "agent",
        "steps": 
        [
            {
                "name": "step to sleep",
                "interpreter": {
                  "skill": {
                    "minVersion": "1.0.0"
                  },
                  "name": "chef-platform/shell-interpreter"
                },
                "command": {
                  "linux": [
                    "sleep 10"
                  ],
                  "windows": [
                    "timeout 10"
                  ]
                },
                "inputs": {},
                "expectedInputs": { },
                "outputFieldRules": {},
                "retryCount": 2,
                "failureBehavior": {
                  "action": "retryThenFail",
                  "retryBackoffStrategy": {
                    "type": "linear",
                    "delaySeconds": 1,
                    "arguments": [1,3,5]
                  }
                },
                "limits": {},
                "conditions": []
            }
        ]
    }
}
actions:
  accessMode: agent
  steps:
  - command:
      linux:
      - sleep 10
      windows:
      - timeout 10
    conditions: []
    expectedInputs: {}
    failureBehavior:
      action: retryThenFail
      retryBackoffStrategy:
        arguments:
        - 1
        - 3
        - 5
        delaySeconds: 1
        type: linear
    inputs: {}
    interpreter:
      name: chef-platform/shell-interpreter
      skill:
        minVersion: 1.0.0
    limits: {}
    name: step to sleep
    outputFieldRules: {}
    retryCount: 2
description: demonstrating running a job using a saved filter
exceptionRules: []
name: job saved filter
scheduleRule: immediate
target:
  executionType: sequential
  groups:
  - batchSize:
      type: number
      value: 5
    distributionMethod: batching
    filterId: --FILTER ID--
    nodeListType: savedFilter
    successCriteria:
    - numRuns:
        type: percent
        value: 100
      status: success
    timeoutSeconds: 300
description = 'demonstrating running a job using a saved filter'
exceptionRules = []
name = 'job saved filter'
scheduleRule = 'immediate'
[actions]
  accessMode = 'agent'
  [[actions.steps]]
    conditions = []
    name = 'step to sleep'
    retryCount = 2.0
    [actions.steps.command]
      linux = ['sleep 10']
      windows = ['timeout 10']
    [actions.steps.expectedInputs]
    [actions.steps.failureBehavior]
      action = 'retryThenFail'
      [actions.steps.failureBehavior.retryBackoffStrategy]
        arguments = [1.0, 3.0, 5.0]
        delaySeconds = 1.0
        type = 'linear'
    [actions.steps.inputs]
    [actions.steps.interpreter]
      name = 'chef-platform/shell-interpreter'
      [actions.steps.interpreter.skill]
        minVersion = '1.0.0'
    [actions.steps.limits]
    [actions.steps.outputFieldRules]
[target]
  executionType = 'sequential'
  [[target.groups]]
    distributionMethod = 'batching'
    filterId = '--FILTER ID--'
    nodeListType = 'savedFilter'
    timeoutSeconds = 300.0
    [target.groups.batchSize]
      type = 'number'
      value = 5.0
    [[target.groups.successCriteria]]
      status = 'success'
      [target.groups.successCriteria.numRuns]
        type = 'percent'
        value = 100.0
Run an action sequentially on multiple node groups
This job template runs an action sequentially on two groups of nodes.
{
    "name":"multi-node-multi-group-job-batching",
    "description": "demonstrating an immediate job executing sequential on multiple nodes with batched rollout",
    "scheduleRule": "immediate",
    "exceptionRules":[],
    "target": {
        "executionType": "sequential",
        "groups":[
            {
                "timeoutSeconds": 300,
                "batchSize": {
                    "type": "number",
                    "value": 2
                },
                "distributionMethod": "batching",
                "successCriteria": [
                    {
                        "numRuns": { "type": "percent", "value": 100 },
                        "status": "success"
                    }
                ],
                "nodeListType":"nodes",
                "nodeIdentifiers":[
                    "--NODE1--",
                    "--NODE2--",
                    "--NODE3--",
                    "--NODE4--",
                    "--NODE5--"
                ]
            },
            {
                "timeoutSeconds": 300,
                "batchSize": {
                    "type": "number",
                    "value": 2
                },
                "distributionMethod": "batching",
                "successCriteria": [
                    {
                        "numRuns": { "type": "percent", "value": 100 },
                        "status": "success"
                    }
                ],
                "nodeListType":"nodes",
                "nodeIdentifiers":[
                    "--NODE6--",
                    "--NODE7--",
                    "--NODE8--"
                ]
            }
        ]
    },
    "actions": {
        "accessMode": "agent",
        "steps":
        [
            {
                "name": "step to sleep for a random period",
                "interpreter": {
                  "skill": {
                    "minVersion": "1.0.0"
                  },
                  "name": "chef-platform/shell-interpreter"
                },
                "command": {
                  "linux": [
                    "sleep $((RANDOM % 120))"
                  ]
                },
                "inputs": {},
                "expectedInputs": { },
                "outputFieldRules": {},
                "retryCount": 1,
                "failureBehavior": {
                  "action": "retryThenFail",
                  "retryBackoffStrategy": {
                    "type": "linear",
                    "delaySeconds": 1,
                    "arguments": [1,3,5]
                  }
                },
                "limits": {},
                "conditions": []
            }
        ]
    }
}actions:
  accessMode: agent
  steps:
  - command:
      linux:
      - sleep $((RANDOM % 120))
    conditions: []
    expectedInputs: {}
    failureBehavior:
      action: retryThenFail
      retryBackoffStrategy:
        arguments:
        - 1
        - 3
        - 5
        delaySeconds: 1
        type: linear
    inputs: {}
    interpreter:
      name: chef-platform/shell-interpreter
      skill:
        minVersion: 1.0.0
    limits: {}
    name: step to sleep for a random period
    outputFieldRules: {}
    retryCount: 1
description: demonstrating an immediate job executing sequential on multiple nodes
  with batched rollout
exceptionRules: []
name: multi-node-multi-group-job-batching
scheduleRule: immediate
target:
  executionType: sequential
  groups:
  - batchSize:
      type: number
      value: 2
    distributionMethod: batching
    nodeIdentifiers:
    - --NODE1--
    - --NODE2--
    - --NODE3--
    - --NODE4--
    - --NODE5--
    nodeListType: nodes
    successCriteria:
    - numRuns:
        type: percent
        value: 100
      status: success
    timeoutSeconds: 300
  - batchSize:
      type: number
      value: 2
    distributionMethod: batching
    nodeIdentifiers:
    - --NODE6--
    - --NODE7--
    - --NODE8--
    nodeListType: nodes
    successCriteria:
    - numRuns:
        type: percent
        value: 100
      status: success
    timeoutSeconds: 300
description = 'demonstrating an immediate job executing sequential on multiple nodes with batched rollout'
exceptionRules = []
name = 'multi-node-multi-group-job-batching'
scheduleRule = 'immediate'
[actions]
  accessMode = 'agent'
  [[actions.steps]]
    conditions = []
    name = 'step to sleep for a random period'
    retryCount = 1.0
    [actions.steps.command]
      linux = ['sleep $((RANDOM % 120))']
    [actions.steps.expectedInputs]
    [actions.steps.failureBehavior]
      action = 'retryThenFail'
      [actions.steps.failureBehavior.retryBackoffStrategy]
        arguments = [1.0, 3.0, 5.0]
        delaySeconds = 1.0
        type = 'linear'
    [actions.steps.inputs]
    [actions.steps.interpreter]
      name = 'chef-platform/shell-interpreter'
      [actions.steps.interpreter.skill]
        minVersion = '1.0.0'
    [actions.steps.limits]
    [actions.steps.outputFieldRules]
[target]
  executionType = 'sequential'
  [[target.groups]]
    distributionMethod = 'batching'
    nodeIdentifiers = ['--NODE1--', '--NODE2--', '--NODE3--', '--NODE4--', '--NODE5--']
    nodeListType = 'nodes'
    timeoutSeconds = 300.0
    [target.groups.batchSize]
      type = 'number'
      value = 2.0
    [[target.groups.successCriteria]]
      status = 'success'
      [target.groups.successCriteria.numRuns]
        type = 'percent'
        value = 100.0
  [[target.groups]]
    distributionMethod = 'batching'
    nodeIdentifiers = ['--NODE6--', '--NODE7--', '--NODE8--']
    nodeListType = 'nodes'
    timeoutSeconds = 300.0
    [target.groups.batchSize]
      type = 'number'
      value = 2.0
    [[target.groups.successCriteria]]
      status = 'success'
      [target.groups.successCriteria.numRuns]
        type = 'percent'
        value = 100.0
Install nginx
This job template uses several steps with inputs and outputs to install nginx, start it, and verify that it’s running.
{
    "name": "nginx-install",
    "description": "A simple demonstration that shows a multi-step job that declares outputs and evaluates inputs to install or configure applications conditionally",
    "scheduleRule": "immediate",
    "exceptionRules": [],
    "target": {
        "executionType": "sequential",
        "groups": [
            {
                "timeoutSeconds": 160,
                "batchSize": {
                    "type": "number",
                    "value": 1
                },
                "distributionMethod": "rolling",
                "successCriteria": [
                    {
                        "numRuns": {
                            "type": "percent",
                            "value": 100
                        },
                        "status": "success"
                    }
                ],
                "nodeListType": "nodes",
                "nodeIdentifiers": [
                    "--NODE1--"
                ]
            }
        ]
    },
    "actions": {
        "accessMode": "agent",
        "steps": [
            {
                "interpreter": {
                  "skill": {
                    "minVersion": "1.0.0"
                  },
                  "name": "chef-platform/shell-interpreter"
                },
                "command": {"linux": [
                    "which nginx >/dev/null && echo true || echo false"
                ]},
                "inputs": {},
                "expectedInputs": {},
                "outputFieldRules": {
                    "NGINX_FOUND": {
                        "source": "stdout",
                        "sourceType": "output",
                        "extractMethod": "content",
                        "expression": "",
                        "required": true,
                        "sensitive": false
                    }
                },
                "retryCount": 2,
                "failureBehavior": {
                    "action": "retryThenFail",
                    "retryBackoffStrategy": {
                        "type": "linear",
                        "delaySeconds": 1,
                        "arguments": []
                    }
                },
                "limits": {},
                "conditions": [],
                "name": "a step to check nginx presence"
            },
            {
                "interpreter": {
                  "skill": {
                    "minVersion": "1.0.0"
                  },
                  "name": "chef-platform/shell-interpreter"
                },
                "inputs": {},
                "expectedInputs": {
                    "NGINX_FOUND": {
                        "type": "string",
                        "sensitive": false,
                        "required": true,
                        "default": ""
                    }
                },
                "outputFieldRules": {},
                "conditions": [
                    {
                        "inputName": "NGINX_FOUND",
                        "operator": "eq",
                        "value": "false\n"
                    }
                ],
                "command": {"linux": [
                    "yum install nginx -y 2>&1 >/dev/null",
                    "systemctl enable nginx 2>&1 >/dev/null",
                    "systemctl start nginx 2>&1 >/dev/null"
                ]},
                "retryCount": 2,
                "failureBehavior": {
                    "action": "retryThenFail",
                    "retryBackoffStrategy": {
                        "type": "linear",
                        "delaySeconds": 1,
                        "arguments": []
                    }
                },
                "limits": {},
                "name": "install nginx conditionally"
            },
            {
                "interpreter": {
                  "skill": {
                    "minVersion": "1.0.0"
                  },
                  "name": "chef-platform/shell-interpreter"
                },
                "command": {"linux": [
                    "curl -s http://localhost:80 | grep 'hello world!' >/dev/null && echo true || echo false"
                ]},
                "inputs": {},
                "expectedInputs": {},
                "outputFieldRules": {
                    "EXPECTED_PAGE_FOUND": {
                        "source": "stdout",
                        "sourceType": "output",
                        "extractMethod": "content",
                        "expression": "",
                        "required": true,
                        "sensitive": false
                    }
                },
                "retryCount": 2,
                "failureBehavior": {
                    "action": "retryThenFail",
                    "retryBackoffStrategy": {
                        "type": "linear",
                        "delaySeconds": 1,
                        "arguments": []
                    }
                },
                "limits": {},
                "conditions": [],
                "name": "check if nginx is configured"
            },
            {
                "interpreter": {
                  "skill": {
                    "minVersion": "1.0.0"
                  },
                  "name": "chef-platform/shell-interpreter"
                },
                "inputs": {},
                "expectedInputs": {
                    "EXPECTED_PAGE_FOUND": {
                        "type": "string",
                        "sensitive": false,
                        "required": true,
                        "default": ""
                    }
                },
                "outputFieldRules": {},
                "conditions": [
                    {
                        "inputName": "EXPECTED_PAGE_FOUND",
                        "operator": "eq",
                        "value": "false\n"
                    }
                ],
                "command": {"linux": [
                    "echo '<html><body><h1>hello world!</h1></body></html>' | sudo tee /usr/share/nginx/html/index.html > /dev/null"
                ]},
                "retryCount": 2,
                "failureBehavior": {
                    "action": "retryThenFail",
                    "retryBackoffStrategy": {
                        "type": "linear",
                        "delaySeconds": 1,
                        "arguments": []
                    }
                },
                "limits": {},
                "name": "configure nginx if not already"
            },
            {
                "interpreter": {
                  "skill": {
                    "minVersion": "1.0.0"
                  },
                  "name": "chef-platform/shell-interpreter"
                },
                "command": {"linux": [
                    "curl -s http://localhost:80 | grep 'hello world!'"
                ]},
                "inputs": {},
                "expectedInputs": {},
                "outputFieldRules": {},
                "conditions": [],
                "retryCount": 2,
                "failureBehavior": {
                    "action": "retryThenFail",
                    "retryBackoffStrategy": {
                        "type": "linear",
                        "delaySeconds": 1,
                        "arguments": []
                    }
                },
                "limits": {},
                "name": "check if nginx is properly configured"
            }
        ]
    }
}actions:
  accessMode: agent
  steps:
  - command:
      linux:
      - which nginx >/dev/null && echo true || echo false
    conditions: []
    expectedInputs: {}
    failureBehavior:
      action: retryThenFail
      retryBackoffStrategy:
        arguments: []
        delaySeconds: 1
        type: linear
    inputs: {}
    interpreter:
      name: chef-platform/shell-interpreter
      skill:
        minVersion: 1.0.0
    limits: {}
    name: a step to check nginx presence
    outputFieldRules:
      NGINX_FOUND:
        expression: ""
        extractMethod: content
        required: true
        sensitive: false
        source: stdout
        sourceType: output
    retryCount: 2
  - command:
      linux:
      - yum install nginx -y 2>&1 >/dev/null
      - systemctl enable nginx 2>&1 >/dev/null
      - systemctl start nginx 2>&1 >/dev/null
    conditions:
    - inputName: NGINX_FOUND
      operator: eq
      value: |
        false
    expectedInputs:
      NGINX_FOUND:
        default: ""
        required: true
        sensitive: false
        type: string
    failureBehavior:
      action: retryThenFail
      retryBackoffStrategy:
        arguments: []
        delaySeconds: 1
        type: linear
    inputs: {}
    interpreter:
      name: chef-platform/shell-interpreter
      skill:
        minVersion: 1.0.0
    limits: {}
    name: install nginx conditionally
    outputFieldRules: {}
    retryCount: 2
  - command:
      linux:
      - curl -s http://localhost:80 | grep 'hello world!' >/dev/null && echo true
        || echo false
    conditions: []
    expectedInputs: {}
    failureBehavior:
      action: retryThenFail
      retryBackoffStrategy:
        arguments: []
        delaySeconds: 1
        type: linear
    inputs: {}
    interpreter:
      name: chef-platform/shell-interpreter
      skill:
        minVersion: 1.0.0
    limits: {}
    name: check if nginx is configured
    outputFieldRules:
      EXPECTED_PAGE_FOUND:
        expression: ""
        extractMethod: content
        required: true
        sensitive: false
        source: stdout
        sourceType: output
    retryCount: 2
  - command:
      linux:
      - echo '<html><body><h1>hello world!</h1></body></html>' | sudo tee /usr/share/nginx/html/index.html
        > /dev/null
    conditions:
    - inputName: EXPECTED_PAGE_FOUND
      operator: eq
      value: |
        false
    expectedInputs:
      EXPECTED_PAGE_FOUND:
        default: ""
        required: true
        sensitive: false
        type: string
    failureBehavior:
      action: retryThenFail
      retryBackoffStrategy:
        arguments: []
        delaySeconds: 1
        type: linear
    inputs: {}
    interpreter:
      name: chef-platform/shell-interpreter
      skill:
        minVersion: 1.0.0
    limits: {}
    name: configure nginx if not already
    outputFieldRules: {}
    retryCount: 2
  - command:
      linux:
      - curl -s http://localhost:80 | grep 'hello world!'
    conditions: []
    expectedInputs: {}
    failureBehavior:
      action: retryThenFail
      retryBackoffStrategy:
        arguments: []
        delaySeconds: 1
        type: linear
    inputs: {}
    interpreter:
      name: chef-platform/shell-interpreter
      skill:
        minVersion: 1.0.0
    limits: {}
    name: check if nginx is properly configured
    outputFieldRules: {}
    retryCount: 2
description: A simple demonstration that shows a multi-step job that declares outputs
  and evaluates inputs to install or configure applications conditionally
exceptionRules: []
name: nginx-install
scheduleRule: immediate
target:
  executionType: sequential
  groups:
  - batchSize:
      type: number
      value: 1
    distributionMethod: rolling
    nodeIdentifiers:
    - --NODE1--
    nodeListType: nodes
    successCriteria:
    - numRuns:
        type: percent
        value: 100
      status: success
    timeoutSeconds: 160
description = 'A simple demonstration that shows a multi-step job that declares outputs and evaluates inputs to install or configure applications conditionally'
exceptionRules = []
name = 'nginx-install'
scheduleRule = 'immediate'
[actions]
  accessMode = 'agent'
  [[actions.steps]]
    conditions = []
    name = 'a step to check nginx presence'
    retryCount = 2.0
    [actions.steps.command]
      linux = ['which nginx >/dev/null && echo true || echo false']
    [actions.steps.expectedInputs]
    [actions.steps.failureBehavior]
      action = 'retryThenFail'
      [actions.steps.failureBehavior.retryBackoffStrategy]
        arguments = []
        delaySeconds = 1.0
        type = 'linear'
    [actions.steps.inputs]
    [actions.steps.interpreter]
      name = 'chef-platform/shell-interpreter'
      [actions.steps.interpreter.skill]
        minVersion = '1.0.0'
    [actions.steps.limits]
    [actions.steps.outputFieldRules]
      [actions.steps.outputFieldRules.NGINX_FOUND]
        expression = ''
        extractMethod = 'content'
        required = true
        sensitive = false
        source = 'stdout'
        sourceType = 'output'
  [[actions.steps]]
    name = 'install nginx conditionally'
    retryCount = 2.0
    [actions.steps.command]
      linux = ['yum install nginx -y 2>&1 >/dev/null', 'systemctl enable nginx 2>&1 >/dev/null', 'systemctl start nginx 2>&1 >/dev/null']
    [[actions.steps.conditions]]
      inputName = 'NGINX_FOUND'
      operator = 'eq'
      value = "false\n"
    [actions.steps.expectedInputs]
      [actions.steps.expectedInputs.NGINX_FOUND]
        default = ''
        required = true
        sensitive = false
        type = 'string'
    [actions.steps.failureBehavior]
      action = 'retryThenFail'
      [actions.steps.failureBehavior.retryBackoffStrategy]
        arguments = []
        delaySeconds = 1.0
        type = 'linear'
    [actions.steps.inputs]
    [actions.steps.interpreter]
      name = 'chef-platform/shell-interpreter'
      [actions.steps.interpreter.skill]
        minVersion = '1.0.0'
    [actions.steps.limits]
    [actions.steps.outputFieldRules]
  [[actions.steps]]
    conditions = []
    name = 'check if nginx is configured'
    retryCount = 2.0
    [actions.steps.command]
      linux = ["curl -s http://localhost:80 | grep 'hello world!' >/dev/null && echo true || echo false"]
    [actions.steps.expectedInputs]
    [actions.steps.failureBehavior]
      action = 'retryThenFail'
      [actions.steps.failureBehavior.retryBackoffStrategy]
        arguments = []
        delaySeconds = 1.0
        type = 'linear'
    [actions.steps.inputs]
    [actions.steps.interpreter]
      name = 'chef-platform/shell-interpreter'
      [actions.steps.interpreter.skill]
        minVersion = '1.0.0'
    [actions.steps.limits]
    [actions.steps.outputFieldRules]
      [actions.steps.outputFieldRules.EXPECTED_PAGE_FOUND]
        expression = ''
        extractMethod = 'content'
        required = true
        sensitive = false
        source = 'stdout'
        sourceType = 'output'
  [[actions.steps]]
    name = 'configure nginx if not already'
    retryCount = 2.0
    [actions.steps.command]
      linux = ["echo '<html><body><h1>hello world!</h1></body></html>' | sudo tee /usr/share/nginx/html/index.html > /dev/null"]
    [[actions.steps.conditions]]
      inputName = 'EXPECTED_PAGE_FOUND'
      operator = 'eq'
      value = "false\n"
    [actions.steps.expectedInputs]
      [actions.steps.expectedInputs.EXPECTED_PAGE_FOUND]
        default = ''
        required = true
        sensitive = false
        type = 'string'
    [actions.steps.failureBehavior]
      action = 'retryThenFail'
      [actions.steps.failureBehavior.retryBackoffStrategy]
        arguments = []
        delaySeconds = 1.0
        type = 'linear'
    [actions.steps.inputs]
    [actions.steps.interpreter]
      name = 'chef-platform/shell-interpreter'
      [actions.steps.interpreter.skill]
        minVersion = '1.0.0'
    [actions.steps.limits]
    [actions.steps.outputFieldRules]
  [[actions.steps]]
    conditions = []
    name = 'check if nginx is properly configured'
    retryCount = 2.0
    [actions.steps.command]
      linux = ["curl -s http://localhost:80 | grep 'hello world!'"]
    [actions.steps.expectedInputs]
    [actions.steps.failureBehavior]
      action = 'retryThenFail'
      [actions.steps.failureBehavior.retryBackoffStrategy]
        arguments = []
        delaySeconds = 1.0
        type = 'linear'
    [actions.steps.inputs]
    [actions.steps.interpreter]
      name = 'chef-platform/shell-interpreter'
      [actions.steps.interpreter.skill]
        minVersion = '1.0.0'
    [actions.steps.limits]
    [actions.steps.outputFieldRules]
[target]
  executionType = 'sequential'
  [[target.groups]]
    distributionMethod = 'rolling'
    nodeIdentifiers = ['--NODE1--']
    nodeListType = 'nodes'
    timeoutSeconds = 160.0
    [target.groups.batchSize]
      type = 'number'
      value = 1.0
    [[target.groups.successCriteria]]
      status = 'success'
      [target.groups.successCriteria.numRuns]
        type = 'percent'
        value = 100.0
Adhoc node filter
This job template defines an adhoc filter for Linux nodes, with matching IP addresses, and the Courier Runner and Chef Gohai skills installed.
{
    "name":"nodeman-query-immediate-linux",
    "description": "Demonstrating a courier job using an adhoc search query against different sample atttributes as target",
    "scheduleRule": "immediate",
    "exceptionRules":[],
    "target": {
        "executionType": "sequential",
        "groups":[
            {
                "timeoutSeconds": 3000,
                "batchSize": {
                    "type": "number",
                    "value": 1
                },
                "distributionMethod": "batching",
                "successCriteria": [
                    {
                        "numRuns": { "type": "percent", "value": 100 },
                        "status": "success"
                    }
                ],
                "nodeListType":"filter",
                "filter": { "constraints": {
                    "attributes": [
                        {
                            "name": "kernel_name",
                            "operator": "=",
                            "value": [
                                "Linux"
                            ]
                        },
                        {
                            "name": "primary_ip",
                            "operator": "MATCHES",
                            "value": [
                                "^172\\.31\\.29.*"
                            ]
                        }
                    ],
                    "skills": [
                        {
                            "name": "courier-runner",
                            "version": [
                                "<= 1.0.66"
                            ]
                        },
                        {
                            "name": "chef-gohai",
                            "version": [
                                "= 0.1.0"
                            ]
                        }
                    ]
                }
            }
            }
        ]
    },
    "actions": {
        "accessMode": "agent",
        "steps":
        [
            {
                "name": "step to sleep",
                "interpreter": {
                  "skill": {
                    "minVersion": "1.0.0"
                  },
                  "name": "chef-platform/shell-interpreter"
                },
                "command": {
                  "linux": [
                    "sleep 10"
                  ],
                  "windows": [
                    "timeout 10"
                  ]
                },
                "inputs": {},
                "expectedInputs": { },
                "outputFieldRules": {},
                "retryCount": 2,
                "failureBehavior": {
                  "action": "retryThenFail",
                  "retryBackoffStrategy": {
                    "type": "linear",
                    "delaySeconds": 1,
                    "arguments": [1,3,5]
                  }
                },
                "limits": {},
                "conditions": []
            }
        ]
    }
}actions:
  accessMode: agent
  steps:
  - command:
      linux:
      - sleep 10
      windows:
      - timeout 10
    conditions: []
    expectedInputs: {}
    failureBehavior:
      action: retryThenFail
      retryBackoffStrategy:
        arguments:
        - 1
        - 3
        - 5
        delaySeconds: 1
        type: linear
    inputs: {}
    interpreter:
      name: chef-platform/shell-interpreter
      skill:
        minVersion: 1.0.0
    limits: {}
    name: step to sleep
    outputFieldRules: {}
    retryCount: 2
description: Demonstrating a courier job using an adhoc search query against different
  sample atttributes as target
exceptionRules: []
name: nodeman-query-immediate-linux
scheduleRule: immediate
target:
  executionType: sequential
  groups:
  - batchSize:
      type: number
      value: 1
    distributionMethod: batching
    filter:
      constraints:
        attributes:
        - name: kernel_name
          operator: =
          value:
          - Linux
        - name: primary_ip
          operator: MATCHES
          value:
          - ^172\.31\.29.*
        skills:
        - name: courier-runner
          version:
          - <= 1.0.66
        - name: chef-gohai
          version:
          - = 0.1.0
    nodeListType: filter
    successCriteria:
    - numRuns:
        type: percent
        value: 100
      status: success
    timeoutSeconds: 3000
description = 'Demonstrating a courier job using an adhoc search query against different sample atttributes as target'
exceptionRules = []
name = 'nodeman-query-immediate-linux'
scheduleRule = 'immediate'
[actions]
  accessMode = 'agent'
  [[actions.steps]]
    conditions = []
    name = 'step to sleep'
    retryCount = 2.0
    [actions.steps.command]
      linux = ['sleep 10']
      windows = ['timeout 10']
    [actions.steps.expectedInputs]
    [actions.steps.failureBehavior]
      action = 'retryThenFail'
      [actions.steps.failureBehavior.retryBackoffStrategy]
        arguments = [1.0, 3.0, 5.0]
        delaySeconds = 1.0
        type = 'linear'
    [actions.steps.inputs]
    [actions.steps.interpreter]
      name = 'chef-platform/shell-interpreter'
      [actions.steps.interpreter.skill]
        minVersion = '1.0.0'
    [actions.steps.limits]
    [actions.steps.outputFieldRules]
[target]
  executionType = 'sequential'
  [[target.groups]]
    distributionMethod = 'batching'
    nodeListType = 'filter'
    timeoutSeconds = 3000.0
    [target.groups.batchSize]
      type = 'number'
      value = 1.0
    [target.groups.filter]
      [target.groups.filter.constraints]
        [[target.groups.filter.constraints.attributes]]
          name = 'kernel_name'
          operator = '='
          value = ['Linux']
        [[target.groups.filter.constraints.attributes]]
          name = 'primary_ip'
          operator = 'MATCHES'
          value = ['^172\.31\.29.*']
        [[target.groups.filter.constraints.skills]]
          name = 'courier-runner'
          version = ['<= 1.0.66']
        [[target.groups.filter.constraints.skills]]
          name = 'chef-gohai'
          version = ['= 0.1.0']
    [[target.groups.successCriteria]]
      status = 'success'
      [target.groups.successCriteria.numRuns]
        type = 'percent'
        value = 100.0
Schedule a job
This job template runs an action using a schedule.
{
    "name":"single-node-job-future-linux",
    "description": "demonstrating a scheduled job executing once",
    "scheduleRule": "RRULE:FREQ=MINUTELY;COUNT=2;WKST=MO",
    "exceptionRules":[],
    "target": {
        "executionType": "sequential",
        "groups":[
            {
                "timeoutSeconds": 300,
                "batchSize": {
                    "type": "number",
                    "value": 1
                },
                "distributionMethod": "batching",
                "successCriteria": [
                    {
                        "numRuns": { "type": "percent", "value": 100 },
                        "status": "success"
                    }
                ],
                "nodeListType":"nodes",
                "nodeIdentifiers":[
                    "--NODE1--"
                ]
            }
        ]
    },
    "actions": {
        "accessMode": "agent",
        "steps":
        [
            {
                "name": "step to sleep",
                "interpreter": {
                  "skill": {
                    "minVersion": "1.0.0"
                  },
                  "name": "chef-platform/shell-interpreter"
                },
                "command": {
                  "linux": [
                    "sleep 10"
                  ],
                  "windows": [
                    "timeout 10"
                  ]
                },
                "inputs": {},
                "expectedInputs": { },
                "outputFieldRules": {},
                "retryCount": 2,
                "failureBehavior": {
                  "action": "retryThenFail",
                  "retryBackoffStrategy": {
                    "type": "linear",
                    "delaySeconds": 1,
                    "arguments": [1,3,5]
                  }
                },
                "limits": {},
                "conditions": []
            }
        ]
    }
}actions:
  accessMode: agent
  steps:
  - command:
      linux:
      - sleep 10
      windows:
      - timeout 10
    conditions: []
    expectedInputs: {}
    failureBehavior:
      action: retryThenFail
      retryBackoffStrategy:
        arguments:
        - 1
        - 3
        - 5
        delaySeconds: 1
        type: linear
    inputs: {}
    interpreter:
      name: chef-platform/shell-interpreter
      skill:
        minVersion: 1.0.0
    limits: {}
    name: step to sleep
    outputFieldRules: {}
    retryCount: 2
description: demonstrating a scheduled job executing once
exceptionRules: []
name: single-node-job-future-linux
scheduleRule: RRULE:FREQ=MINUTELY;COUNT=2;WKST=MO
target:
  executionType: sequential
  groups:
  - batchSize:
      type: number
      value: 1
    distributionMethod: batching
    nodeIdentifiers:
    - --NODE1--
    nodeListType: nodes
    successCriteria:
    - numRuns:
        type: percent
        value: 100
      status: success
    timeoutSeconds: 300
description = 'demonstrating a scheduled job executing once'
exceptionRules = []
name = 'single-node-job-future-linux'
scheduleRule = 'RRULE:FREQ=MINUTELY;COUNT=2;WKST=MO'
[actions]
  accessMode = 'agent'
  [[actions.steps]]
    conditions = []
    name = 'step to sleep'
    retryCount = 2.0
    [actions.steps.command]
      linux = ['sleep 10']
      windows = ['timeout 10']
    [actions.steps.expectedInputs]
    [actions.steps.failureBehavior]
      action = 'retryThenFail'
      [actions.steps.failureBehavior.retryBackoffStrategy]
        arguments = [1.0, 3.0, 5.0]
        delaySeconds = 1.0
        type = 'linear'
    [actions.steps.inputs]
    [actions.steps.interpreter]
      name = 'chef-platform/shell-interpreter'
      [actions.steps.interpreter.skill]
        minVersion = '1.0.0'
    [actions.steps.limits]
    [actions.steps.outputFieldRules]
[target]
  executionType = 'sequential'
  [[target.groups]]
    distributionMethod = 'batching'
    nodeIdentifiers = ['--NODE1--']
    nodeListType = 'nodes'
    timeoutSeconds = 300.0
    [target.groups.batchSize]
      type = 'number'
      value = 1.0
    [[target.groups.successCriteria]]
      status = 'success'
      [target.groups.successCriteria.numRuns]
        type = 'percent'
        value = 100.0