Links

Dynamic/Cloud Inventory

In nearly all real-world production cases, managed computers, nodes, or systems (whatever we call them) dynamically come and go at all times, and what is currently present is rarely defined by files on disk or in version control. Cloud tools may create systems from CI/CD workflows, or systems may be controlled by autoscaling groups.
In these cases, Jet's on-disk inventory format cannot be the "source of truth" for the list of groups, hostnames, and often even variable information.
Reminder About When Inventory Is Needed
In local mode and in the future "Planetary Scale" modes, inventory is not required and this section can be skipped. Inventory is an SSH-only feature.
SSH Dynamic inventory in Jet works by calling one or more executable scripts or programs that return a specific JSON format to tell jet about groups, hosts, and variables.
To use an inventory script, we simply invoke jet passing the executable file as a parameter:
$ chmod +x ~/some_script.py
$ jetp show --inventory ~/some-script.py --groups all
$ jetp ssh --inventory ~/some_script.py --playbook pb1.yml
These scripts could contact a cloud provider, commercial CMDB, in-house database, or essentially any program. All that matters is they return the correct JSON data on standard output. Development of your own in-house inventory scripts (or forking our own) is encouraged, should available ones (detailed below) not work exactly how you like.
Adding Variables From Files
Inventory variables from dynamic inventory can still be supplemented with variable information from the filesystem.
If the inventory script has a "group_vars/" or "host_vars/" directory in the same directory as the inventory script and parallel to it, they will added to the groups and hosts returned by the inventory script.
This is sometimes much easier and clearer than trying to assign variables through something like cloud tags, which some inventory scripts support.
See Inventory Variables On Disk for how this works.

Where To Find Inventory Scripts

While you can write your own inventory scripts, you can find several for popular inventory sources in the Jeti project at github.com/jetporch/jeti.
"Jeti" stands for "Jetporch Inventory", just like "Jetp" is (sort of) short for "Jetporch playbooks".
Because the inventory script specification is based on JSON, it is relatively easy to write inventory scripts in a wide variety of programming languages. If you write an inventory script for a popular computing platform, we would be interested in your contributing of it to Jeti.
For ease of collective maintenance, we would accept python and Rust in the jeti tree. Because these modules will usually be waiting on external APIs, there is not much need for them to be implemented in Rust, but Rust's compiler checks are great to have and encourage more refactoring and keeping things up to date compared to python. Still, you may find python easier to write and that is also fine!
Legacy Code Still Present In Jeti
Jeti was started as a fork of the Ansible inventory scripts from Ansible 2.9, the last Ansible release that contained stand-alone inventory script examples in tree before moving to an ansible-specific plugin architecture.
Over time, any legacy references to "module_utils" from the ansible codebase can be removed until it ends up being a self-contained set of scripts without any dependencies on "lib/jeti". Most of "lib/jeti" deals with (unwanted) python 2.X support, which is not important to the Jetporch project, since we can assume a newer control machine and do not require python to be installed on remote systems.
Also, when looking at scripts in the project you may see many different parsing command line options. Jet does not use these, and many of these were added for debugging purposes or to support a legacy Ansible parameter "--host" that Jet does not use. These can also be removed over time from Jeti. See the Jeti readme for more information.
Ansible is a registered trademark of Red Hat, Inc.

Dynamic Inventory Specification

With some discussion of Jeti out of the way, let's describe the JSON format if you want to write your own inventory script instead of using one that has already been developed.
At the most basic level, the inventory script should return a JSON map (also called a "hash table" or "dictionary") with each top level key being the name of a Jet group.
Each element can contain different elements, all of which are optional. We'll start off with an example that just shows children and hosts.
{
"webservers": {
"children" : [
"webservers_raleigh",
"webservers_newyork"
],
},
"webservers_raleigh" : {
"hosts" : [
"raleigh-www-01.example.com",
"raleigh-www-02.example.com"
],
},
"webservers_newyork" : {
"hosts" : [
"newyork-www-01.example.com",
"newyork-www-02.example.com"
]
},
"dbservers" : {
"hosts" : [
"db1.example.com",
"db2.example.com"
]
}
}
In the above example, the JSON defines multiple groups - in this example, webservers, webservers_raleigh, webservers_newyork, and dbservers.
The valid subkeys "children" and "hosts" are both optional. For example, the group "webservers" has no hosts as direct members, but it does contain subgroups that have hosts.
More About Calling Conventions, Input, and Output
How should an inventory script behave? It should merely output JSON when called.
There is no need to have sorted keys or pretty-print the JSON, this is only shown for explaining the format. It might be helpful to pretty-print JSON if called with a particular flag, but Jet will not pass any flags to the script or program. Inventory programs/scripts in Jet do not pass any arguments or set any environment variables.
Any data loading from a configuration file, environment variable, and so on is up to that particular inventory script/program to decide. Typically they will load a file with the same base filename as the inventory script and a different extension.
If the program/script would like to return an error, it can return a non-zero exit code and any standard out or standard error messages from that failure will be shown to the user.

Adding Group Variables

Variables can be added to any group by adding a "vars" keyword to the group definition. The "vars'" must be a map/hashtable/dictionary as shown below, and can contain nested values, including hashes and arrays:
"webservers_raleigh" : {
"hosts" : [
"raleigh-www-01.example.com",
"raleigh-www-02.example.com"
],
"vars" : {
"foo" : "bar",
"baz_port" : "8080"
}
}
Must Groups Have Hosts In Them?
Groups without hosts in them can still have variables assigned to them, just like groups can have hosts assigned to them without variables. Having a completely empty group without subgroups is not very useful, but it will also not result in an error either. The inventory script loading code in Jet will not warn if a group with variables is never assigned hosts, because it is expected for the script code to construct inventory correctly.

Adding Host Variables

Host specific variables can be added by adding a "hostvars" section to any group.
"webservers_raleigh" : {
"hostvars" : {
"raleigh-www-01.example.com" : {
"asdf" : "example value"
}
"raleigh-www-02.example.com" : {
"asdf" : "example value 2"
}
}
}
Shortcuts
When using "hostvars" in the script's per-group JSON, it is not required to have a seperate "hosts" JSON element, though both will be processed if present. Hostvars could be considered an 'advanced' way to specify hosts. This value can also be an empty dictionary "{}".
Magic Groups?
To support compatibility with legacy ansible inventory scripts, host specific variables can also be added to an imaginary top-level group named "_meta". If writing a new inventory script, don't do this.
Group names that start with a hyphen will not be created as real addressable groups in Jet. Jet interprets hyphen-meta as referring to what Jet calls the "all" group, though explicitly saying "all" instead of "_meta" is preferred.
Every group in Jet is implicitly added to the "all" group, there is no need to define an "all" group unless wanting to assign variables to that group, in which case they basically would serve as default variables, having a precedence level just a tiny amount higher than the defaults keyword in a playbook.
Magic Variables?
Very few variables in Jet are considered magic and these are described in the SSH chapter. They are all host-specific inventory variables.