preview
We're still working on this feature, but we'd love for you to try it out!
This feature is currently provided as part of a preview program pursuant to our pre-release policies.
Schema
Workflow definitions are written in YAML. Keys use a camelCase naming convention.
name (Required)
- Type: String
- Format: Must conform to the regex
^[A-Za-z_][A-Za-z0-9_-]*$. - Max. length: 100
- Description:
namevalues are case-insensitive. For example,ExampleWorkflow,exampleworkflow, andEXAMPLEWORKFLOWare all considered to represent the same workflow definition.
description (Optional)
- Type: String
- Format: Must conform to the regex
^[A-Za-z0-9 _-]*$. - Max. length: 200
- Description: A
descriptionof the workflow that explains its purpose.
workflowInputs (Optional)
Type: Map of maps
Max. size: 100
Description: A map of workflow inputs that the workflow accepts.
Example:
workflowInputs:myInput1:type: StringmyInput2:type: NumberdefaultValue: 42workflowInputs.<inputName>(Required)- Type: String (conforming to expression-safe pattern)
- Min. length: 1
- Max. length: 50
- Description: The name of the workflow input.
workflowInputs.<inputName>.type(Required)- Type: Enum (Boolean, List, Map, String, Int, Float)
- Description: The data type of the workflow input.
workflowInputs.<inputName>.defaultValue(Optional)- Type: Any; must conform to
type. - Description: The default value for the workflow input.
- Type: Any; must conform to
steps (Required)
- Type: Array of maps
- Description: The steps to be performed when the workflow definition is run. There must be at least one step.
重要
Steps will run in the order they’re defined in the
stepsarray.If a different ordering is desired, a “jump” can be performed by setting the
steps[*].nextproperty to the name of the desired step to jump to.steps[*].name(Required)- Type: String (conforming to expression-safe pattern; cannot be
end) - Max. length: 100
- Description: The name of the step to be referenced by
steps[*].next. It cannot be the special keywordsend,continue, orbreak, as these are used to indicate a terminating step, a continuation of a loop, or to break out of a loop.
- Type: String (conforming to expression-safe pattern; cannot be
steps[*].type(Required)- Type: String
- Description: The type of the step, indicating what the step does when run. Refer to Step Types for the available options.
steps[*].next(Optional)- Type: String (conforming to expression-safe pattern)
- Description:
- The name of the next step to run when this step completes successfully. The special keyword
endcan be used to indicate that this step should be the last one to run. - If
nextis omitted, the following entry in the definition’sstepsarray will be used as the implicit next step. If there is no following entry, the workflow will be completed.
- The name of the next step to run when this step completes successfully. The special keyword
Step Types
action
A step that runs a specific action. Refer to Action Catalog for the available options.
steps[*].action(Required)Type: String
Description: The fully qualified name of the action function to run. It should follow the following convention:
<company domain>.<category of work>.<action name in camelCase>Example:
- Action using New Relic services (e.g. through NerdGraph):
newrelic.dashboards.getDashboard - Action using Slack:
slack.chat.postMessage
- Action using New Relic services (e.g. through NerdGraph):
steps[*].version(Required)- Type: String
- Description: The version of the action function to run.
steps[*].inputs(Optional)- Type: Map of values (includes expressions)
- Description:
- The inputs to pass to the action function. The specific inputs accepted are defined by each action.
- Inputs can use expressions. See the Expressions Strings section for details.
重要
No sensitive data (no API keys or secrets, no PII, PHI or any personally identifiable data) should be passed-in as arguments.
steps[*].inputs.selectors(Optional)Type: list of map in the form of
namewithexpression.Description:
- The
selectorsinput allows to redefine the output to only return the specified elements. - Expression can be used. See the Expressions Strings section for details.
- The
Example
- In the given example we are getting the
pageUrlandstatusDescriptionas response of http.get action.
name: statusdescription: A workflow for checking the status of New Relic componentssteps:- name: query1type: actionaction: http.getversion: 1inputs:url: "https://status.newrelic.com/api/v2/status.json"selectors:- name: statusCodeexpression: '.statusCode'- name: pageUrlexpression: '.responseBody | fromjson | .page.url'- name: statusDescriptionexpression: '.responseBody | fromjson | .status.description'- name: logOutput1type: actionaction: newrelic.ingest.sendLogsversion: 1inputs:logs:- message: "status is '${{ .steps.query1.outputs.statusDescription }}' details at ${{ .steps.query1.outputs.pageUrl }}"- In the given example we are getting the
loop
A loop will iterate over a given collection defined by in and create loop variables index and element for each of its iteration. These loop variables are accessible within the loop only with expression ${{ .steps.<loopStepName>.loop.element }} or ${{ .steps.<loopStepName>.loop.index }
For more details see below:
steps[*].for(Required)- Type: constant
- Description: Signal starting of a loop
steps[*].in(Required)Type: string (expression)
Description: An expression that need to evaluate to a collection of elements.
steps[*].steps(Optional)Description: Steps to be executed each iteration of the loop. See definition for steps above.
Example:
name: myWorkflowsteps:- name: loopSteptype: loopfor:in: "${{ [range(1; 5)] }}""steps:- name: step1type: actionaction: newrelic.ingest.sendLogsversion: 1inputs:logs:- message: "Loop: ${{ .steps.loopStep.loop.element }}"
switch
A step that checks various conditionals and takes the first branch that evaluates to true.
A switch can contain any number of condition elements in a list. It will check the conditions in order and process the first one that evaluates to true. If none evaluate to true, it will run its next step as defined in steps[*].next
steps[*].switch(Required)- Type: array
- Description: An array of switch cases, specifying the ordered list of conditions to evaluate.
steps[*].switch[*].condition(Required)- Type: string (expression)
- Description: The condition of the switch case. If evaluated to true, the case’s next step will be executed.
steps[*].switch[*].next(Required)- Type: string (conforming to expression-safe pattern)
- Description: The name of the step to run if the case’s condition evaluates to true. The special keyword end can be used to indicate that this step should be the last one to run.
- name: hasCompletedtype: switchswitch:- condition: ${{ .steps.waitForCompletion.outputs.automationExecutionStatus == "Failed" }}next: displayError- condition: ${{ .steps.waitForCompletion.outputs.automationExecutionStatus == "Success" }}next: displaySuccessnext: displayUnexpected
wait
A step that causes the workflow run to wait a certain number of seconds before continuing. It can also listen for one or more signals. If no signal is received during the wait, it will proceed as normal. The signals are defined in a list. Each signal must have a corresponding next step defined. The first signal to be received is the one that will be processed. The value received for the signal will be stored in the step output for the wait step and can be used for logic our processing in later steps.
Example:
name: waitSignalExampleworkflowInputs:steps:- name: waitSteptype: waitseconds: 300signals: [{name: 'mySignalName', next: 'firstStep'}]- name: endSteptype: actionaction: newrelic.ingest.sendLogsversion: 1inputs:logs:- message: "didn't get signal"next: end- name: firstSteptype: actionaction: newrelic.ingest.sendLogsversion: 1inputs:logs:- message: ${{ .steps.waitStep.outputs.signalInputs.myString }}steps[*].seconds(Required)- Type: number
- Description: The number of seconds to wait before continuing the workflow run.
steps[*].signals- Type: array
- Description: The signals which, when received, will divert the program flow.
steps[*].signals[*].name- Type: string
- Description: The name of the signal to listen for.
steps[*].signals[*].next- Type: string
- Description: The Step to execute if the specified signal is received.
Shared Types
Expression strings
Several properties accept string values with embedded expressions that are evaluated during workflow execution, allowing for dynamic values to be used within workflow definitions. Expression strings can contain one or multiple expressions, each of which are enclosed within double curly braces. The content within the braces is evaluated using jq.
jq provides the ability to access and operate on values in many ways. For example, the length of a workflow input string could be achieved with the following:
${{ .workflowInputs.myString | length }}
To build and test JQ expression this tool can be used.
Expression properties
A number of properties can be accessed with expressions. These properties live in a “scope” object, so expressions must start with a period (.) to access those properties of the scope object.
The available properties are:
workflowInputs- object containing the inputs passed to the workflow on start.- Example:
${{ .workflowInputs.myInput }}
- Example:
steps- object containing a property for each step in the workflowsteps.<stepName>- object containing properties for a specific stepsteps.<stepName>.outputs- object containing result properties, specific to the step/action.- Example:
${{ .steps.myStep.outputs.myResult }}
- Example:
Expression evaluation results
A single jq expression can evaluate to any JSON type, but it’s important to note that the final result of an entire expression string will be dependent on the string content (if any) surrounding the expression(s).
If the entirety of an expression string consists of a single expression, then it will be evaluated to the jq expression’s result—maintaining the JSON type of the result. For example, if a workflow is passed an array as input, the string ${{ .workflowInputs.myArray }} would evaluate to an array. This can be useful for passing complex data within a workflow.
If the expression string contains content other than a single expression, then it will be evaluated to a string result. For example, this occurs when an expression has content before/after it or if the string has multiple expressions within it. Each expression within the string is evaluated and converted to a string representation.
Example:
For the following examples, assume myArray has a value of [1, 2, 3].
Expression string | Result data | Result type |
|---|---|---|
| [1, 2, 3] | array of numbers |
| 3 | number |
| true | boolean |
| "Input is not empty: true" | string |
| " has length 3" | string |
Expression-Safe Pattern
Properties that can be used in expressions must conform to the following regex:
^[A-Za-z_][A-Za-z0-9_]*$
Secret References
Secret values can be used in actions via reference strings that specify the name of a secret to look up in the Secrets Service. To reference a secret in a workflow definition, use the syntax:
${{ :secrets:<SECRET_NAME> }}for a secret not in anamespace${{ :secrets:<NAMESPACE>:<SECRET_NAME> }}for a secret in anamespace
An expression string can contain a mix of secret references and JQ expressions and/or multiple secret references.
Examples:
steps: - name: bearer_auth type: action action: http.post inputs: headers: Authorization: Bearer ${{ :secrets:<SECRET_NAME> }}Examples
- Hello World
name: helloWorlddescription: 'A hello world workflow'
workflowInputs: name: type: String defaultValue: World required: false validations: - type: maxLength errorMessage: "name must be at most 100 characters" length: 100 slackTokenSecret: type: String defaultValue: "${{ :secrets:SLACK_TOKEN }}" slackChannel: type: String defaultValue: my-channel validations: - type: regex errorMessage: "A slack channel name must be lowercase and can only contain letters, numbers, and hyphens" pattern: "^[a-z0-9\\-]+$" required: true
steps: - name: init1 type: assign inputs: greeting: Hello ${{ .workflowInputs.name }}
- name: logName type: action action: newrelic.ingest.sendLogs version: 1 inputs: logs: - message: ${{ .steps.init1.outputs.greeting }}
- name: waiting1 type: wait seconds: 1
- name: queryForLog type: action action: newrelic.nrdb.query version: 1 inputs: query: >- FROM Log SELECT * WHERE message LIKE '${{ .steps.init1.outputs.greeting }}'
- name: checkResult type: switch switch: - condition: ${{ .steps.queryForLog.outputs.results | length > 0 }} next: FoundMessage
- name: waitingMessage type: action action: slack.chat.postMessage version: 1 inputs: channel: ${{ .workflowInputs.slackChannel }} text: Waiting for log message... token: ${{ .workflowInputs.slackTokenSecret }} next: waiting1
- name: FoundMessage type: action action: slack.chat.postMessage version: 1 inputs: channel: ${{ .workflowInputs.slackChannel }} text: Found message! ${{ .steps.queryForLog.outputs.results[0].message }} token: ${{ .workflowInputs.slackTokenSecret }}