Skip to main content
Version: 2.4.1

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 a prop value of 2.
  • some.nested[*].prop>1 matches because one or more elements has a prop value greater than 1.
  • some.nested[*].prop>3 does not match because there is no element with a prop 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:

Find nodes where reported.cpu_count is greater than 3, and desired.clean is true
> 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:

OperationDescription
= 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.
inProperty is one of the following values. The value has to be an array.
not inProperty 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"

    note

    The 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 or double. 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.

Example Predicates
Select nodes with names exactly matching
name == "sunset"
Same as previous; parentheses are optional if the string is not a number and does not contain special characters
name == sunset
Select nodes with more than 2 instance_cores
instance_cores > 2
Select nodes where the name matches the regular expression sun.*
name =~ "sun.*"
Select nodes where the name is either
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.

Examples
Select nodes where reported.name is either sunrise or sunset
> search name in [sunset, sunrise]
Select instance nodes where reported.name is sunrise
> search is(instance) and name==sunrise
Select aws_ec2_instance nodes of specific type or more than 2 cores
> search is(aws_ec2_instance) and (instance_type=="m5a.large" or instance_cores>2)
Select instance nodes in an account which name includes the term
> search is(instance) and /ancestors.account.reported.name=~engineering
Select all instance nodes wich are not in the engineering account
> 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.

Select 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.

Select all load balancers in a specific subnet range
> search is(load_balancer) and in_subnet(public_ip_address, "167.123.0.0/16")