Search Filters
Selecting Nodes by Kind​
In order to select nodes by a specific type, the search syntax supports the is(<kind>)
function. The term is(instance)
would select the EC2 instance above, but also all other instances, e.g. Google Cloud instances, while the term is(aws_ec2_instance)
would select only EC2 instances from AWS.
You can get a list of all available kinds via the kind
CLI command.
Selecting Nodes by ID​
Nodes can be selected by their ID via the id(xyz)
function. This function can be used globally no matter which section is used. The id that is used here is a synthetic identifier generated by the collector for every resource.
Selecting Nodes by Predicate​
In order to filter for specific attributes of a node, it is possible to define predicates. A predicate always has the syntax: <property_path> <operation> <value>
(e.g. answer!=42
).
Property Path​
The property_path
is the path to the property in the JSON structure.
A nested property can be accessed by defining its dot-delimited path in the object structure. For example, some.nested.prop
has the value 42
in the following JSON structure:
{ "some": { "nested": { "prop": 42 } } }
Noncompliant Keys​
If the path contains special characters (e.g., .
) or is otherwise noncompliant, the affected portion(s) of the path should be surrounded by backticks.
For example, the path some.`non.compliant.key`.prop
is used to access the property with value 42
in the below JSON structure: some.`non.compliant.key`.prop
.
{ "some": { "non.compliant.key": { "prop": 42 } } }
Arrays​
If a property is an array, specific elements can be accessed using index notation.
In the below JSON, the path some.nested[0]
references first element of the array with path some.nested
, and some.nested[2]
points to the third (and last) element:
{ "some": { "nested": [1, 2, 3] } }
In arrays of objects, object elements can also be accessed using index notation.
The path some.nested[0].prop
has a value of 1
here:
{ "some": { "nested": [{ "prop": 1 }, { "prop": 2 }, { "prop": 3 }] } }
It is also possible to define filters based on object element properties. For example, the path some.nested[0].prop > 2
matches if the first array element has a prop
value greater than 2.
We can also check if any array element has a prop
value greater than 2. To do so, we would use the path some.nested[*].prop > 2
. The *
wildcard symbol indicates that all elements of the array should be checked, and that any single element satisfying the defined condition is sufficient for a match.
Take the following example:
{
"some": {
"nested": [
{ "prop": 1 },
{ "prop": 2 },
{ "prop": 3 }
]
}
}
some.nested[*].prop==2
matches because the second element has aprop
value of 2.some.nested[*].prop>1
matches because one or more elements has aprop
value greater than 1.some.nested[*].prop>3
does not match because there is no element with aprop
value greater than 3.
Property Sections​
Most properties are defined in the reported
section, and the CLI interprets property paths relative to the reported
section by default. Thus, the path to property reported.name
can simply be written as name
.
To target properties not in the reported
section, prefix the property path with a slash (/
) for it to be interpreted as an absolute path:
> search cpu_count > 3 and /desired.clean==true
The section that is used to interpret the property paths is defined by the environment parameter section
. As stated earlier, this variable defaults to reported
.
Since the CLI allows to define environment variables as part of the CLI command, this behaviour can be adjusted easily:
> section=reported search cpu_count>3 and /desired.clean==true
is semantically the same as this query, which interprets all paths from the root
> section=/ search reported.cpu_count>3 and desired.clean==true
is semantically the same as this query, which interprets all paths relative to the desired section
> section=desired search /reported.cpu_count>3 and clean==true
The examples above only illustrate the mechanics of property paths. We suggest to keep the default, as the examples below assume the default setting.
Operation​
The operation
is one of the following:
Operation | Description |
---|---|
= or == | Property is equal to the provided value. |
!= | Property is not equal to the provided value. |
<= | Property is less than or equal to the provided value. |
>= | Property is greater than or equal to the provided value. |
> | Property is greater than the provided value. |
< | Property is less than the provided value. |
~ or =~ | Property conforms to the given regexp. Only applicable to strings. |
!~ | Property is not conform to the given regexp. Only applicable to strings. |
in | Property is one of the following values. The value has to be an array. |
not in | Property is not one of the following values. The value has to be an array. |
Value​
The value
can be any JSON literal or JSON conform value.
A JSON conform value is:
string
Examples:
"hello world"
,"test"
noteThe query parser is gracious with quotes. If there are no white space and no special characters, it is possible to omit quotes. In case you see parse errors, try adding quotes to your strings.
number
(integers and floating-point numbers)Examples:
23
,12.123
The model itself clearly defines if a number is
int32
,int64
,float
ordouble
. From the query point of view, all numbers are treated the same way.boolean
Examples:
true
,false
array
Example:
[1, true, "test"]
object
Example:
{"a": 1, "b": 2}
null
This can be useful to query for properties that are unset or do not exist.
name == "sunset"
name == sunset
instance_cores > 2
name =~ "sun.*"
name in ["sunset", "sunrise"]
Arrays​
A property inside an array is accessed via [position]
. So to access the first element of an array we can write [0]
.
If the position is not known or does not matter we can write [*]
.
If the filtered property is an array, it is also possible to define a criteria based on elements of the array using one of the operator modifier: all
, any
or none
in front of the operation.
Let us assume following document: {"reported": { "test": [1, 2, 3, 4]}}
, we could define a query like test all >= 1
or test any > 2
or test none > 100
, which would match the document.
Combining Selections​
All listed selections can be combined with and
and or
clauses. In order to define precedence, enclose terms with parentheses. If no brackets are defined, the terms are evaluated from left to right.
It is possible to negate a simple predicate or more complex term with not
.
> search name in [sunset, sunrise]
> search is(instance) and name==sunrise
> search is(aws_ec2_instance) and (instance_type=="m5a.large" or instance_cores>2)
> search is(instance) and /ancestors.account.reported.name=~engineering
> search is(instance) and not /ancestors.account.reported.name==engineering
Selecting Nodes with a specific property key​
Nodes can be selected based on the fact that a specific property exists, no matter which value this property has. The has_key(parent, property)
function will select all nodes where the property parent
has property property
.
Example: We want to find all volumes that are tagged with the tag owner
.
> search is(volume) and has_key(tags, owner)
Note: we could have used the search search is(volume) and tags.owner!=null
instead. This would select all volumes with an owner tag, where the owner tag is not null. The has_key
function ignores the value of the property and only returns if the property exists.
Selecting Nodes by IPV4 addresses in a certain subnet range​
For resources with IPV4 addresses, it is possible to select nodes in a specific subnet range. The function in_subnet(ipv4_property, cidr)
will select all nodes where the property ipv4_property
is in the subnet range cidr
.
Example: We want to find all load balancer, where the public ipv4 address is in the subnet range 167.123.0.0/16
.
> search is(load_balancer) and in_subnet(public_ip_address, "167.123.0.0/16")