Make Workflow Steps Conditional

You can specify that workflow steps are executed only when specified conditions are met. Setting conditions can help you:

  • Make a workflow more flexible — for example, you could install an anti-virus program only on Windows VMs.
  • Add an extra level of approval to a workflow — for example, you could require a two-stage approval if the user requests resource changes.
  • Simplify the approval process — for example, you could create an approval workflow that will trigger the approval process only if the monthly cost of the request is greater than a specified amount. If the amount is lower than what you specify, the approval workflow will run, but no approval emails will be sent, and the request will move to the Approved state.

Define conditional expressions

To set a condition, you must define a valid expression that's composed with a combination of the following elements:

  • Variables — Predefined expressions that reference Commander metadata. For a list of the available variables, see Variables Reference.
  • Operators — Symbols that indicate the mathematical, relational, or logical operations to perform in the expression. The operators must be lower case. See Define conditional expressions.
  • Constants — The constants can be numbers, Booleans, or strings.

The workflow type determines what variables you can use. For more information, see Add Data to Workflows With Variables.

Syntax rules

Commander uses the following syntax rules for conditional expressions.

These syntax rules apply to both conditional workflow steps and conditional change requests. For more information, see Make Change Requests Conditional.

  • Invalid conditions are evaluated to false.
  • You must enclose each variable in quotation marks.
  • When using Boolean operators, you must enclose each condition in parentheses. For example:
    ("#{target.state}" -eq running) -and ("#{target.cloudAccount.type}" -eq amazon_aws)
  • Parameters with spaces must be enclosed in double quotation marks. For example:
    "2019/03/12 08:30"
  • Because conditions are parsed after variable substitution has occurred, if a variable value will contain spaces, the entire variable must be enclosed in double quotation marks. For example:
    "#{request.requestedServices[1].components[1].description}"
  • Escaping of characters isn't supported. Escape characters are passed as is.
  • An empty string "" is used to indicate null or not set.
  • If a variable can be resolved as a number, a Boolean entity, or a date, it will be treated as such; otherwise it will be interpreted as a string.
    • Number: A positive and negative floating point number or integer
    • Boolean: True or false, case-insensitive
    • Date: YYYY/MM/DD hh:mm:ss
  • A variable will be resolved as a date if it matches one of these patterns:

    YYYY/MM/DD hh:mm:ss

    YYYY/MM/DD hh:mm

    YYYY/MM/DD hh:

    YYYY/MM/DD

    where:

    YYYY = four-digit year

    MM = two-digit month (01=January, etc.)

    DD = two-digit day of month (01 through 31)

    hh = two digits of hour (00 through 23) (am/pm NOT allowed)

    mm = two digits of minute (00 through 59)

    ss = two digits of second (00 through 59)

  • Accuracy of date matching is determined by the specified date.

    Example 1: "#{target.settings.expiryDate}" -gt 2021/01/01 would resolve to true for VMs with an expiry date after Jan 1st, 2021 at 00:00:00.

    Example 2: "#{target.settings.expiryDate}" -lt "2021/03/12 08:30" would resolve to true for VMs with an expiry date before March 12, 2021 at 08:30:00.

    Example 3: "#{target.settings.expiryDate}" -ge "2021/04/01 13:00" would resolve to April 1st, 2021 at 1:00:00 PM or later.

  • For strings and enumerations:
    • All string comparisons are case-insensitive.
    • If the data type of a Commander variable is an enumeration, then the list of string choices is limited.
  • If the left and right side of the expression aren't the same data type, the expression will evaluate to false. For example:
    "#{target.cpuCount}" -eq true

    In this example, the data type for the left side of the expression is Integer, and the data type for the right side is Boolean, so this expression will evaluate to false.

  • If the left side of an expression can't immediately be interpreted by Commander, and the right side of the expression is a date, the left side will also be evaluated as a date. For example:
    "#{any.numeric.property}" -eq 2021/01/01

    This expression would be evaluated as two dates.

Troubleshooting

When you encounter a syntax error, ensure that your condition follows Commander's conditional expression syntax rules.

Also check for the following:

  • Mismatched and misplaced parentheses.
  • An operator without a hyphen preceding it.
  • Unclosed quotes.

Example: Create conditional approval workflow

The following procedure shows you how to create a workflow that triggers the approval process only if the monthly cost is greater than 100 USD:

  1. Go to Configuration > Self-Service.
  2. Click the Approval tab.
  3. Create an approval workflow for new service requests or change requests.
  4. On the Assigned Groups page, decide whether to apply this workflow globally or to specific users or groups.
  5. In the step details section:
    • Click AddSend Approval Email .
    • For Step Execution, select Execute when conditions are met.
    • Click Edit, then enter the following condition:

      "#{request.cost.monthly}" -gt 100

    • Click OK to return to the Steps page.
    • In the Address List field, enter one or more email addresses (semicolon-separated).
    • Customize the Email Body as required.
  6. Complete the rest of the wizard.

    For more information, see Create Approval Workflows for Service Requests.

Example: Make a workflow step conditional on a previous step

To make a workflow step conditional on whether a previous step has run, use the variable #{steps[x].skipped}, where x is a step number (beginning at 1) or name. This variable returns True if the workflow step did not run, and is supported in all workflow types.

For example, you might want to allow Service Portal users to back up their VMs using a script you've developed, but this requires the VM to be powered off before it runs. You also want to make sure that if the user requested the backup while the VM was powered on, the VM is powered on again after the backup.

  1. A Perform Power Action step, with the action Start, with a condition to run only if the VM is powered off. The condition would read:
    "#{target.state}" -ne "Not running">

    It's important to handle this step this way, instead of making the execution conditional on the state Running, because VM can have several states (including Saved, Starting, Stopping, Suspended and more).

  2. Some other action.
  3. A Perform Power Action step, with the action Start, with a condition to run only if Step 1 did not run. The condition would read:

    "#{steps[1].skipped}" -eq true

Example: Workflows that only run for specific service types

Commander supports multiple service types, including:

  • VM
  • Virtual Service (vApp)
  • Database
  • Load Balancer
  • Auto Scaling Group
  • Application Stack

You can use the "#{target.type}" variable to run a workflow step only on a particular service type. This variable allows you to support multiple service types in a single workflow.

For example, to specify that a step that applies only to load balancers, enter the following condition:

"#{target.type}" -eq "Load Balancer"

The #{target.type} variable is supported in the following workflow types:

  • Approval workflows for change requests
  • Component-level completion workflows
  • Command workflows

More example step conditions

The following examples apply to approval workflows for change requests and to completion workflows.

  • Specify that a step will be carried out only if the requested number of CPUs is greater than two:
    "#{target.settings.cpuCount}" -gt 2
  • Specify that a step will be carried out only on Windows VMs:
    "#{target.guestOS}" -contains Microsoft
  • Specify that a step will be carried out only if resource settings (CPU, memory or storage) have been modified on the request form:
    "#{request.resourcesChanged}" -eq true

More complex examples using Boolean operators

Conditional Send Approval Email step

It's possible to use a Send Approval Email to notify the admin to create an Active Directory computer account before the workflow continues, but only if the previous Execute Approval Script step completed successfully, and the requested service is a Windows VM.

To make the Send Approval Email step conditional, you can use the following expression:

("#{steps[2].exitCode}" -eq 0) -and ("#{request.services[1].components[1].description}" -contains Windows)

Note that because the service description may contain spaces, the entire variable is surrounded by double quotes.

Conditional Perform Power Action steps

It's possible to power off specific types of running VMs.

Each of the following examples uses a Perform Power Action step with the action Stop, but with a different conditional expression.

Power off running AWS VMs:

("#{target.state}" -eq running) -and ("#{target.cloudAccount.type}" -eq amazon_aws)

Power off running VMs, unless they're Azure VMs:

("#{target.state}" -eq running) -and (-not ("#{target.cloudAccount.type}" -eq ms_azure))

Power off running AWS and VMware VMs:

("#{target.state}" -eq running) -and ("#{target.cloudAccount.type}" -eq amazon_aws) -or ("#{target.cloudAccount.type}" -eq vc)