Learn how to help your team build confidently (and securely!) in prod in our upcoming Tech Talk: Sign up here.

After decorating your services with tags, you can define checks in OpsLevel to verify arbitrary metadata about your services. These docs show examples of how you can leverage Tag Defined Checks to do exactly that.

The Tag Defined Check

Tag Defined Check

Verify Key Exists

Without any advanced options, a Tag Defined check can be used to verify that a tag with a particular key exists on a service, or many services. For example, you can create such a check to ensure that all of your services have a flag, such as internet-facing, defined. This type of a tag can be used as a filter for even more powerful checks, so it can be useful to be sure that this tag is not missing on any of your services.

Internet Facing Tag Check

Verify Value Satisfies Condition

Using the advanced options, a Tag Defined check can also be used to verify that there exists a tag on a service with a particular key along with some constraints on the tag’s value. For example, the following check ensures that the datastore used by the applicable services is mysql.

Datastore Check

Verify Library Version

Tags can be used to enrich your services with arbitrary metadata. One popular way to enrich services is to decorate them with the important library versions they depend on.

You can then in turn use a Tag Defined check to validate that the version satisfies a given constraint!

What’s In a Version

A valid semantic library version must specify at least the major, minor and patch component. You can also append pre-release tags to the end of a version.

Examples of valid versions: 1.2.3, 1.2.3-alpha, v1.2.3, =v1.2.3.

Examples of invalid versions: 1, 1.2, 1.2-alpha.

See the official SemVer guides for a complete specification on versions (and even a Backus-Naur Form Grammar for versions, if that’s your cup of tea!).

Once you’ve formulated a version, go ahead and add a tag to your service with the value being the version. For example, if a service uses Node.js version 12.18.4, you might add the tag node-version:12.18.4 to that service. (One popular way of automating this tagging is to integrate OpsLevel’s GraphQL API into your CI pipeline in order to upsert version tags on every CI run.)

Version Constraints

Cool, so you can decorate a service with the versions of its dependencies in a structured format. But how can you use these version tags to measure the compliance of your services with desired library versions? You can use the Satisfies Version Constraint predicate as an advanced option in a Tag Defined check!

For example, the following check ensures that services have a tag with key node-version with a version that is at least 12.0.0. In other words, such a check ensures that services use a version of Node.js that is at least 12.0.0.

Version Constraint Check

The following table defines the most common version comparators you can use in conjunction with our Tag Defined Checks.

Comparator Description
= The “equals” comparator can be used to ensure that your library version matches an expected version exactly (that is, the major, minor and patch are all equal). This operator is, however, optional. A constraint without any operator will default to using the “equals” comparator.
< The “less than” comparator can be used to ensure that your library version is less than an expected version (with order of precedence being (1) major (2) minor and (3) patch).
<= The “less than or equal to” comparator is similar to the < comparator, except an exact match against an expected version is also allowed.
> The “greater than” comparator is analagous to the < comparator, except the library version must be greater than the expected version.
>= The “greater than or equal to” comparator is analagous to the <= comparator, except the library version must be greater than or equal to the expected version.
~ The “tilde” comparator ensures that the library version matches the major and minor versions of an expected version, but can have an equal or greater patch version.
^ The “caret” comparator can be used to ensure that the library version matches the major version of an expected version, but can have an equal or greater minor version.
~> The “pessimistic” comparator can be used to ensure that a library version matches the expected version up to the last component specified. See this Ruby Gems guide for a complete description.
x An x in any position of an expected version behaves like a wildcard. That is, any version can be substituted for the component containing the x.

The following table shows some examples of version constraints along with examples of versions that would and wouldn’t be accepted.

Version Constraint Accepted Versions Unaccepted Versions
<1.2.3 1.2.2, 1.1.1, 0.4.0 1.2.3, 1.3.0, 2.0.0
~1.2.3 1.2.3, 1.2.4, 1.2.42 1.2.2, 1.3.0, 2.0.0
^1.2.3 1.2.0, 1.2.4, 1.9.1 1.1.1, 0.9.0, 2.0.0
~>1.2 1.2.0, 1.2.1, 1.2.42 1.1.1, 1.3.0, 2.0.0
1.2.x 1.2.0, 1.2.1, 1.2.42 1.1.0, 1.3.0, 2.0.0
1.2.x || 1.4.x 1.2.0, 1.4.0 1.1.0, 1.3.0, 2.0.0
1.2.3 - 1.3.3 1.2.3, 1.3.0, 1.3.3 1.2.2, 1.3.4

See the node-semver guides for an exhaustive list of comparators you can use to build advanced version constraints.

Hopefully these examples can help you harness the power of tags in OpsLevel. As always, if you have any questions, or any new ideas for Tag Defined checks, feel free to reach out to us at info@opslevel.com.