Conditions
In event driven automation a condition determines if a rule fires (runs its action).
Example:
condition: event.status == "enabled"
- Each of the condition(s) can use information from
Event received
Previously saved events within the rule
Longer term facts about the system
Variables provided by the user at startup saved as vars
- When writing conditions
use the event prefix when accessing data from the current event
use the fact prefix when accessing data from the set_facts actions in the rulebook
use the events prefix when assigning variables and accessing data within the rule
use the facts prefix when assigning variables and accessing data within the rule
use the vars prefix when accessing variables passed in via –vars and –env-vars
Note
A condition cannot contain Jinja style substitution when accessing variables passed in from the command line, we loose the data type information and the rule engine will not process the condition. Instead use the vars prefix to access the data passed in from the command line
- A condition can contain
One condition
Multiple conditions where all of them have to match
Multiple conditions where any one of them has to match
Supported Operators
Conditions support the following operators:
Name |
Description |
---|---|
== |
The equality operator for strings and numbers |
!= |
The non equality operator for strings and numbers |
> |
The greater than operator for numbers |
< |
The less than operator for numbers |
>= |
The greater than equal to operator for numbers |
<= |
The less than equal to operator for numbers |
+ |
The addition operator for numbers |
- |
The subtraction operator for numbers |
* |
The multiplication operator for numbers |
and |
The conjunctive add, for making compound expressions |
or |
The disjunctive or |
is defined |
To check if a variable is defined |
is not defined |
To check if a variable is not defined |
<< |
Assignment operator, to save the matching events or facts with events or facts prefix |
not |
Negation operator, to negate boolean expression |
Examples
Single condition
name: An automatic remediation rule condition: event.outage == true action: run_playbook: name: remediate_outage.yml
When an event comes with outage
attribute as true, the specified playbook is executed.
Multiple conditions where all of them have to match
name: All conditions must match condition: all: - event.target_os == "linux" - event.tracking_id == 345 action: debug:
As we receive events from the source plugins we send them to the appropriate rule set sessions running in the rule engine. With multiple conditions the rule engine will keep track of the conditions that have matched and wait for the next event to come in which might match other conditions. Once all the conditions have been met, it will return you all the events that matched, which can be used in action.
Note
Note that this case the engine will consider all the different events until meet the conditions, regardless of whether those events come from one or multiple sources. Multiple conditions with
all
are not equivalent to a single condition with theand
operator.If you want to match only one event using multiple attributes the rule must use a single condition with the
and
operator:name: One condition combining attributes condition: event.target_os == "linux" and event.tracking_id == 345 action: debug:
Multiple conditions where any one of them has to match
name: Any condition can match condition: any: - event.target_os == "linux" - event.target_os == "windows" action: debug:Note
Note that this case the engine will consider all the different events until meet the conditions, regardless of whether those events come from one or multiple sources. Multiple conditions with
any
are not equivalent to a single condition with theor
operator.If you want to match only one event using multiple attributes the rule must use a single condition with the
or
operator:name: One condition combining attributes condition: event.target_os == "linux" or event.target_os == "windows" action: debug:
Multiple conditions with facts and events and all of one of them have to match
name: Condition using both a fact and an event condition: all: - fact.meta.hosts == "localhost" - event.target_os == "windows" action: debug:
Condition with fact and event
name: Condition using a set_fact fact and an event condition: all: - facts.first << fact.custom.expected_index is defined - event.i == facts.first.custom.expected_index action: debug:
In the above example the custom.expected_index was set using the set_fact action in the running of the rulebook
Condition with vars and event
name: Condition using a passed in variable and an event condition: all: - event.year == vars.person.year - event.age == vars.person.age action: debug:
In the above example the person.year and person.age was passed in a variables file via --vars
from the
command line to ansible-rulebook.
Logical and
name: Multiple Attribute match from a single event condition: event.target_os == "linux" and event.version == "1.1" action: debug:
Logical or
name: Match any one attribute from a single event condition: event.version == "2.0" or event.version == "1.1" action: debug:
Combining logical operators
You can combine multiple and
operators:
name: Combining and operators condition: event.version == "2.0" and event.name == "example" and event.alert_count > 10 action: debug:
If you combine and
and or
operators they must be enclosed in parenthesis:
name: Combining and -and- or operators condition: ((event.i > 100 and event.i < 200) or (event.i > 500 and event.i < 600)) action: debug:name: Combining and -and- or operators condition: (event.i > 100 and event.i < 200) or event.i > 1000 action: debug:
Multiple conditions with assignment
When a condition is evaluated if the condition passes the matching event it is stored in well known attribute(s) called m_0, m_1, m_2….. You can optionally alias these attribute(s) using the << operator. For example:
name: multiple conditions condition: all: - events.first << event.i == 0 - events.second << event.i == 1 - events.third << event.i == events.first.i + 2 action: debug: first: "{{ events.first }}" second: "{{ events.second }}" third: "{{ events.third }}"
name: multiple conditions using default assignments condition: all: - event.i == 0 - event.i == 1 - event.i == events.m_0.i + 2 action: debug: first: "{{ events.m_0 }}" second: "{{ events.m_1 }}" third: "{{ events.m_2 }}"
Multiple condition with default assignments
name: multiple conditions condition: all: - event.i == 1 - event.i == 2 - event.i == events.m.i + 3 action: debug: first: "{{events.m}}" second: "{{events.m_1}}" third: "{{events.m_2}}"
The first match is stored as m, and the subsequent ones are stored as m_1, m_2 …
Single condition assignment (Not supported)
name: assignment ignored condition: event.first << event.i == 0 action: debug: event: "{{event}}"
Negation Example
name: negation condition: not (event.i > 50 or event.i < 10) action: print_event:
FAQ
- Example:
name: send to debug condition: event.payload.eventType != 'GET' action: debug:
In the above case if any of the event.payload.eventType is undefined the condition is ignored and doesn’t match anything.
- Example:
name: rule1 condition: event.msg is defined action: retract_fact: fact: msg: "{{event.msg}}"
- Example:
name: rule2 condition: fact.msg is not defined action: set_fact: fact: msg: Hello World