Documentation
How Yamlix decides what a variable resolves to, what it deliberately refuses to decide, and what to do when it tells you something you did not expect.
Requirements and install
Yamlix requires a JetBrains IDE of build 2025.2 or newer. It declares no upper build bound, so it is not disabled by an IDE upgrade.
It depends only on the IntelliJ Platform and the YAML support bundled with it. There is no Python dependency, no ansible binary requirement, and no configuration step after install.
- Verified against
- IntelliJ IDEA Community, IntelliJ IDEA Ultimate, PyCharm and GoLand, by the JetBrains Plugin Verifier. These four are the only products actually tested.
- Runs in
- Any JetBrains IDE meeting the build requirement, since the plugin uses only platform and bundled-YAML APIs. Expected to work, not verified.
- Project detection
- Ansible context is detected structurally, per file. The plugin registers no file type and does not claim *.yml, so YAML files that have nothing to do with Ansible behave exactly as they did before.
- Network and data
- Yamlix makes no network calls and collects no data of any kind. There is no telemetry and nothing to opt out of. It never shells out to ansible, so no playbook is executed to answer a question. This site carries no analytics or third-party scripts either.
Where the answers appear
Four places, all of them ones you already use for other languages.
- Ctrl-click a variable
- Lists every declaration, ordered by what applies at the caret rather than alphabetically, so the one you are looking for is the one your eye lands on first. Declarations that exist but are not yet reachable from this point in the play are listed as not in scope here, separately from those that are simply overridden.
- Ctrl-click a reference
- Roles, include_role, include_tasks, vars_files, include_vars, template and copy sources, notify handlers, and hosts: patterns into both INI and YAML inventories. Find Usages goes the other way — from a definition to everything that reads it.
- Quick Documentation
- The effective value per inventory and per host, collapsing the hosts that agree. Where twenty hosts resolve to the same value and one does not, you see two rows, and the interesting one is not buried in eighteen identical ones.
- The tool window
- Every variable the open file uses and defines, each with its effective value, the definition that applies, and the rest folded behind one row. It also reports which playbooks reach the file, values that differ by host, and variables defined here that nothing can ever read because something always overrides them.
- The tool window, on an inventory
- Opening an inventory lists its groups instead: host counts, child groups, the group_vars that apply, and every play whose hosts: pattern selects each group — including the groups nothing targets at all.
- Completion and inspection
- Completion for variable names and hosts: patterns. An inspection reports roles, includes and file references that resolve to nothing.
How resolution works
Yamlix resolves a variable for a position, not for a file.
Ansible layers variable definitions: role defaults sit at the bottom, inventory data above them, values set during the play above that, and a set_fact near the top. A variable that is defined at several of those levels has one value at run time — the highest level that actually applied — and Yamlix reports that value together with every level it beat.
The plugin does not hard-code that ladder from prose documentation. The ordering was established by running ansible-playbook and ansible-inventory against two fixture projects with ansible-core 2.20.4 and recording what actually came out. Those fixtures are the executable specification, and a test asserts the plugin's behaviour cannot drift from them.
Scope is what makes this a question about position rather than about the file. Role vars come into scope once a role has been reached and stay in scope for the rest of the play, including inside a later, different role. An include_vars changes the answer for everything after it and nothing before it. A set_fact behind a when: applies on the hosts where the condition held. So the caret matters: the same variable read in pre_tasks, inside a role, and in post_tasks can give three different values, all of them correct.
Host and inventory matter for the same reason. Inventory data is per host, and group membership can differ between inventories, so the plugin resolves per host and shows the inventories separately rather than merging them into one answer that is true of no host in particular.
Alongside other tools
Yamlix is not a linter and does not replace ansible-lint. It is not a replacement for the official Red Hat Ansible plugin either — that one knows about modules, argument specs, syntax and playbook structure, and Yamlix does not try to. Install it alongside whichever of those you already run; it registers no file type and does not claim *.yml, so nothing else changes behaviour when it is present.
The question it answers is the one the others leave open: given this file, this host and this position in the play, which definition of this variable applies, and what did it beat.
What it cannot know
This section describes intent, not a backlog.
A tool that reads only checked-in files cannot see the run. Where a value depends on the run, Yamlix reports it as unresolved and shows the raw template as written. It does not expand it into a value that would look authoritative and might be wrong.
- Extra vars (-e)
- Override everything and are supplied on the command line. Nothing in a repository can account for them, so the plugin reports their existence as a standing caveat rather than pretending the resolved value is final.
- Gathered facts
- Exist only after a play runs against a host. A fact-templated include_vars therefore has a set of candidate files, not one. Yamlix lists every candidate, marks them conditional, and promotes none — the variable still resolves, to the highest definition that does not depend on facts.
- register
- Holds the result of a task that has not been executed. The variable is known to exist; its value is not, and is shown as unresolved.
- hostvars
- Reaches across hosts at run time, into data that includes facts. Resolved where the underlying definition is static, unresolved where it is not.
- lookup()
- Reads the environment, the filesystem, or an external system at run time. Never evaluated; the call is shown as written.
- Vault
- Encrypted values are not decrypted. The definition site is reported, so you can see that the variable is defined there and at what precedence, without the plugin handling your secrets.
Known limitations
- Tool window applicability is decided once
- Whether the tool window applies to a project is determined when the project opens. A repository that gains its first ansible.cfg during a session will not show the window until the next start. Restart the IDE and it appears.
- Extra vars are invisible
- As above, and worth stating twice: a value overridden with -e at run time will not match what the plugin shows, and the plugin has no way to detect that it was.
- Conditional definitions are listed, not ranked
- Where several candidates depend on a run-time condition, the plugin shows all of them without ordering them by likelihood. There is no likelihood to compute.
Troubleshooting
- "Not defined in this project", but it plainly is
- Almost always a layout problem rather than a resolution problem: the plugin did not find the ansible.cfg you meant it to use, so it is looking for roles and inventories somewhere else. Check that the ansible.cfg governing this code is inside the project, and that the project root is the directory you actually run ansible from.
- A roles_path that resolves from elsewhere
- roles_path entries are relative to the working directory ansible is invoked from. If you run playbooks from a subdirectory, or from a wrapper script that changes directory first, a path that is correct at run time can point outside the project as the plugin reads it. Making the entry absolute, or opening the project at the directory you invoke from, resolves it.
- The tool window is missing
- See the applicability rule above. If the project gained its ansible.cfg after it was opened, restart the IDE.
- A value does not match the run
- Check for extra vars first. After that, check the position: the plugin answers for the caret, and a value read in pre_tasks is legitimately different from the same value read in post_tasks.
Licence, source and reporting issues
Yamlix for Ansible is open source under the Apache License 2.0. The source, the fixture projects and the test suite are all in the repository, including the assertions that record what ansible-core actually produced.
Bug reports and feature requests go to GitHub issues. A report that includes the relevant fragment of ansible.cfg and the layout of the project is usually enough to reproduce a resolution problem.
Trademark
Not affiliated with, endorsed by, or sponsored by Red Hat. Ansible is a trademark of Red Hat, Inc.