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.
Schema properties
Property | Required or Optional | Type | Format | Constraints | Description |
|---|---|---|---|---|---|
| Required | String | Must conform to regex | Max length: 100 | The |
| Optional | String | Must conform to regex | Max length: 200 | A |
| Optional | Map of maps | Max size: 100 | A map of workflow inputs that the workflow accepts. See detailed properties below. |
workflowInputs
Example:
workflowInputs: myInput1: type: String myInput2: type: Number defaultValue: 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.
- Type: Enum (
workflowInputs.<inputName>.defaultValue(Optional)- Type: Any; must conform to
type. - Description: The default value for the workflow input.
- Type: Any; must conform to
workflowInputs.<inputName>.required(Optional)- Type: Boolean (
True,False). - Description: Default value of this field is "True".
- Type: Boolean (
workflowInputs.<inputName>.enumValues(Optional)- Type: List (
String). - Description: Default value of this field is empty List
{}. This is required when workflowInput type is Enum.
- Type: List (
workflowInputs.<inputName>.validations(Optional)- Type: Array of maps.
- Description: The validations to be performed on the workflow inputs provided by user. This is an optional field. The properties described here are present in all Validation types. Specific Validation Types support additional properties as discussed in Validation types section.
validations[*].type(Required)- Type: String
- Description: The type of the validation indicating what validation will be occurring on this field. See Validation Types for more info on each Validation Type.
validations[*].errorMessage(Required)- Type: String
- Description: The error message which user wants to have when a particular validation fails.
Sample YAML for validations
name: calendar_demo
workflowInputs: timezone: type: String defaultValue: 'America/Los_Angeles' validations: - type: regex errorMessage: "The provided timezone is not correct" pattern: "^[A-Za-z]+\/[A-Za-z_]+(?:\/[A-Za-z_]+)?$"
- type: maxLength errorMessage: "Timezone length should be less than 100" length: 100
accountId: type: Int validations: - type: minIntValue errorMessage: "Account id should be greater than 100000" minValue: 100000 - type: maxIntValue errorMessage: "Account id should be less than 9999999" maxValue: 9999999
steps: - name: getCurrentTime type: action action: http.get version: 1 inputs: url: 'https://worldtimeapi.org/api/timezone/${{ .workflowInputs.timezone }}' selectors: - name: timezone expression: '.responseBody | fromjson.abbreviation' - name: datetime expression: '.responseBody | fromjson.datetime'Steps
Property | Required or Optional | Type | Constraints | Description |
|---|---|---|---|---|
| Required | array of maps | The steps to be performed when the workflow definition is run. There must be at least one step. The properties described here are present on all step types. Specific step types support additional properties as described in the Step types section. |
Important
Steps run in the order they are defined in the steps array. If a different ordering is desired, a jump can be performed by setting the steps[*].next property to the name of the desired step to jump.
Common step properties
Property | Required or Optional | Type | Format | Constraints | Description |
|---|---|---|---|---|---|
| Required | String | Must conform to expression-safe pattern cannot be | Max length: 100 | The name of the step to be referenced by |
| Required | String | The type of the step, indicating what the step does when run. Refer to Step types below for the available options. | ||
| Optional | String | Must conform to expression safe pattern | The name of the next step to run when this step completes successfully. The special keyword end can be used to indicate that this step should be the last one to run. If | |
| Optional | Boolean | The |
Step types
Action
A step that runs a specific action. Refer to the 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
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 Expression Strings section for details.
Important
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 maps in the form of
namewithexpression. - Description:
- The
selectorsinput allows you to redefine the output to only return the specified elements. - Expressions can be used. See the Expression strings section for details.
- The
Example:
- In the given example we are getting the
timezoneanddatetimeas response of http.get action.
name: calendar_demoworkflowInputs:timezone:type: StringdefaultValue: 'America/Los_Angeles'accountId:type: Intsteps:- name: getCurrentTimetype: actionaction: http.getversion: 1inputs:url: 'https://worldtimeapi.org/api/timezone/${{ .workflowInputs.timezone }}'selectors:- name: timezoneexpression: '.responseBody | fromjson.abbreviation'- name: datetimeexpression: '.responseBody | fromjson.datetime'- Type: list of maps in the form of
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:
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
conditionelements 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 itsnextstep as defined insteps[*].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
nextstep will be executed. - See the Expression strings section for details.
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
endcan 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 pauses workflow execution for a specified number of seconds before continuing.
The wait step can also listen for one or more signals. Each signal must have a corresponding next step defined in a list. If a signal is received during the wait period, the first signal received will be processed and the workflow will execute its defined next step. If no signal is received, the workflow continues normally after the wait period ends.
The value received from a signal is stored in the wait step's output and can be used in subsequent steps for logic or processing.
Example:
name: waitSignalExample workflowInputs: steps: - name: waitStep type: wait seconds: 300 signals: [{name: 'mySignalName', next: 'firstStep'}] - name: endStep type: action action: newrelic.instrumentation.log version: 1 inputs: message: "didn't get signal" next: end - name: firstStep type: action action: newrelic.instrumentation.log version: 1 inputs: 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.
Assign
A step that defines variables for use throughout the workflow. This step assigns values to variables that can be referenced in subsequent steps. By defining all variables in one place, this step type makes workflows more readable and optimized.
Sample workflow:
name: sampleWorkflowWithAssign description: WorkflowAssignDemo
workflowInputs: initialValue: type: String anotherValue: type: Int
steps: - name: runAction type: action action: internal.http.post version: 1 inputs: url: 'http://localhost:8505/tasks/gc' # temporal-activity-worker-java service port selectors: - name: statusCode expression: '.statusCode' - name: responseBody expression: '.responseBody' - name: variableInitialization type: assign inputs: stringVar: "${{ .workflowInputs.initialValue }}" intVar: "${{ .workflowInputs.anotherValue }}" concatenationVar: "${{ .workflowInputs.initialValue }} - concatenated" booleanVar: true mapVar: key1: "value1" key2: "${{ .workflowInputs.initialValue }}" listVar: - "listItem1" - "${{ .workflowInputs.initialValue }}" - "${{ .workflowInputs.anotherValue }}" statusCode: ${{ .steps.runAction.outputs.statusCode }}
- name: wait type: wait seconds: 2
- name: logVariables type: action action: newrelic.ingest.sendLogs version: 1 inputs: logs: - message: "stringVar: ${{ .steps.variableInitialization.outputs.stringVar }}" - message: "intVar: ${{ .steps.variableInitialization.outputs.intVar }}" - message: "concatenationVar: ${{ .steps.variableInitialization.outputs.concatenationVar }}" - message: "booleanVar: ${{ .steps.variableInitialization.outputs.booleanVar }}" - message: "mapVar: ${{ .steps.variableInitialization.outputs.mapVar | tojson }}" - message: "listVar: ${{ .steps.variableInitialization.outputs.listVar | tojson }}" - message: "statusCode: ${{ .steps.variableInitialization.outputs.statusCode }}"steps[*].inputs(Required)- Type: Map of values (includes expressions)
- Description:
- The inputs are a map of variable names and their assigned values. When secret references are assigned to variables, they remain as secret references and are not converted to their actual values. However, other expressions (such as workflow inputs) are evaluated and converted to their actual values.
- Allowed input types:
Integer,Double,Boolean,String,Array,Map
Validation types
Validation type | Property | Required or Optional | Type | Description |
|---|---|---|---|---|
|
| Required | String | Validates the workflow input value against the provided regex pattern. |
|
| Required | Integer | Validates that the workflow input value should be less than the provided maxValue. |
|
| Required | Integer | Validates that the workflow input value should be greater than the provided minValue. |
|
| Required | Integer | Validates the maximum length of workflow input strings and Collections ( |
Shared types
Expression strings
Several properties accept string values with embedded expressions that are evaluated during workflow execution, enabling dynamic values in workflow definitions.
Expression strings can contain one or more expressions, each enclosed within double curly braces. The content within the braces is evaluated using jq, which provides powerful capabilities to access and operate on values.
Example:
Get the length of a workflow input string:
${{ .workflowInputs.myString | length }}
To validate and test your expressions, use the JQ Playground.
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 }}
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 or action.Example:${{ .steps.myStep.outputs.myResult }}
Expression evaluation results
A single jq expression can evaluate to any JSON type. However, the final result of an expression string depends on whether the string contains only the expression or additional content.
Single expression (preserves JSON type):
If an expression string consists of only one expression with no surrounding content, it evaluates to the jq expression's result while maintaining its original JSON type. For example, ${{ .workflowInputs.myArray }} evaluates to an array. This is useful for passing complex data structures within a workflow.
Multiple expressions or mixed content (converts to string):
If an expression string contains content other than a single expression, it evaluates to a string result. This occurs when an expression has content before or after it, or when the string has multiple expressions within it. Each expression within the string is evaluated and converted to a string representation.
Important
When a jq expression is evaluated to null, a null node is returned. For example the expression ${{ .workflowInputs.missingInput }} returns null if missingInput is not given as workflow input.
Example:
Lets assume myArray has a value of [1, 2, 3].
Expression string | Result data | Result type |
|---|---|---|
|
| Array of numbers |
| 3 | Number |
| True | Boolean |
|
| String |
|
| String |
Expression safe pattern
Properties that can be used in expressions must conform to: ^[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${{ :secrets:<SCOPE>:<NAMESPACE>:<SECRET_NAME> }}for a secret in scope and namespace. scope accepts onlyACCOUNTorORGANIZATIONfor now.
An expression string can contain a mix of secret references and JQ expressions and/or multiple secret references.
Examples:
steps: - name: mySecretStep type: action action: newrelic.instrumentation.log inputs: message: My message licenseKey: ${{ :secrets:<SECRET_NAME> }}steps: - name: bearer_auth type: action action: utils.http.post inputs: headers: Authorization: Bearer ${{ :secrets:<SECRET_NAME> }}Examples
Calendar demo
A complete workflow example that demonstrates multiple workflow features including workflow inputs, HTTP actions, selectors, wait steps, NRQL queries, switch statements, and Slack notifications.
name: calendar_demo
workflowInputs: timezone: type: String defaultValue: 'America/Los_Angeles' accountId: type: Int
steps: - name: getCurrentTime type: action action: http.get version: 1 inputs: url: 'https://worldtimeapi.org/api/timezone/${{ .workflowInputs.timezone }}' selectors: - name: timezone expression: '.responseBody | fromjson.abbreviation' - name: datetime expression: '.responseBody | fromjson.datetime'
- name: logTime type: action action: newrelic.instrumentation.log version: 1 inputs: message: 'DEMO: In the ${{ .steps.getCurrentTime.outputs.timezone }} timezone, the current time is ${{ .steps.getCurrentTime.outputs.datetime }}' licenseKey: ${{ :secrets:STAGING_NEW_RELIC_LICENSE_KEY }}
- name: wait type: wait seconds: 1
- name: queryForLog type: action action: newrelic.nrql.query version: 1 inputs: accountIds: ['${{ .workflowInputs.accountId }}'] query: FROM Log SELECT * WHERE message LIKE 'DEMO:%${{ .steps.getCurrentTime.outputs.datetime }}'
- name: checkQuery type: switch switch: - condition: ${{ .steps.queryForLog.outputs.results | length > 0 }} next: postResultsMessage
- name: postWaitingMessage type: action action: slack.chat.postMessage version: 1 inputs: channel: test-channel-workflow text: Waiting for log message... token: ${{ :secrets:dn_staging_slack_token }} next: wait
- name: postResultsMessage type: action action: slack.chat.postMessage version: 1 inputs: channel: test-channel-workflow text: 'Found log message! ${{ .steps.queryForLog.outputs.results[0].message }}' token: ${{ :secrets:dn_staging_slack_token }}