Ansible development, inside your IDE

Ansible intelligence for JetBrains IDEs.

Ansibility brings deep semantic support for Ansible to PyCharm, IntelliJ IDEA, WebStorm, and PhpStorm. Instead of generic YAML highlighting, it models your entire Ansible project: multi-environment inventories, 22-step variable precedence, transparent vault editing, role argument specs, and live Jinja2 previews.

Target IDE: 2026.2+ (build 262+) JDK: Java 25+ License: GPL-3.0
AI-ASSISTED DEVELOPMENT DISCLAIMER
Transparency Notice

Ansibility has been developed with extensive use of Artificial Intelligence (Large Language Models / LLMs).

While this plugin has been rigorously engineered, strictly typed, and backed by comprehensive unit and integration test suites adhering to authentic ansible-core semantics and specification models, we believe in complete openness and do not want to mislead anyone about how the codebase was constructed.

If you encounter any bugs, hallucinations, edge-case quirks, or unexpected behavior while using the plugin, please report them via the project issue tracker!

playbooks/deploy.yml • Context:
Twoslash Hover Active
# Hover any variable or directive for Twoslash type and source inspector
- name: Deploy web tier
hosts: webservers(inventory group) webserversGroup ScopeInventory: production/hosts.iniContains 2 active hosts: [web-prod-01, web-stage-01]. Target host context switches evaluate against this group hierarchy.Ctrl+B: Navigate to inventory group definition
roles:
- role: nginx_service(role) nginx_serviceAnsible RolePath: roles/nginx_serviceProvides Nginx reverse proxy configuration. Introduces default variable layer (Layer 04) with default port 80.Ctrl+B: Jump to roles/nginx_service/tasks/main.yml
tasks:
- name: Configure listener
ansible.builtin.template(module) ansible.builtin.templateCore ModuleCollection: ansible.builtinTemplate a file out to a target host. Evaluates embedded Jinja2 expressions against the selected host context.Ctrl+B: Open module documentation & schema:
src: "vhost.conf.j2"
dest: "/etc/nginx/sites-available/app.conf"
vars:
listen_port(variable) listen_port: intPrecedence Layer 08Winner: group_vars/production.ymlTCP listener port. Resolves to 443 under active host web-prod-01. Defined in 3 hierarchy layers.Ctrl+B: Jump to winning variable declaration: 443 # Resolved: group_vars/production.yml
^? (variable) listen_port: int = 443 (winner: group_vars/production.yml • Layer 08)
server_workers(variable) server_workers: intPrecedence Layer 12Winner: host_vars/web-prod-01.ymlNginx CPU worker process count override for dedicated high-core host.Ctrl+B: Jump to host_vars declaration: 8 # Resolved: host_vars/web-prod-01.yml
when: {{ listen_port | int > 80 }}
Explain Precedence: listen_port
08
inventory group_vars/production.yml
listen_port: 443 Active Winner
07
inventory group_vars/all.yml
listen_port: 8080 (Overridden)
04
roles/nginx_service/defaults/main.yml
listen_port: 80 (Overridden)
group_vars/production/vault.yml • Vault ID: prod_vault
# Hover on tokens for Shiki/Twoslash envelope inspect; click 🔒 to decrypt
database_credentials(dictionary) database_credentialsYAML DictContains database connection parameters including transparently encrypted Vault passwords.:
db_user: "app_prod_user"
🔒 db_password(vault secret) db_password: !vaultAES-256Vault ID: prod_vault • Format: 1.2Encrypted Ansible Vault scalar envelope. In-editor peek and in-place editing active with disk-sync leak prevention.Click 🔒 gutter lock to reveal plaintext: !vault |
^? !vault | $ANSIBLE_VAULT;1.2;AES256;prod_vault (AES-256 ciphertext block)
$ANSIBLE_VAULT;1.2;AES256;prod_vault
36396434313532393339316538393562386234323233306161363539653738363231366164
34653531633534343162386236353931363630653634353436323634373339343336336336
Ansible Vault Features
🔒 In-Editor Plaintext Reveal: Click the gutter lock marker for timed & masked preview dialogs.
✏️ In-Place Edit & Rekey: Edit encrypted blocks directly in the IDE and re-encrypt seamlessly.
🛡️ Disk-Sync Protection: Whole-file encrypted tabs veto unencrypted temporary files from being written to disk.
⚡ Password-Free Linting: Statically inspects envelopes for trailing whitespace (ANS-V103) and malformed headers (ANS-V101) without passwords.
roles/database/tasks/main.yml • Spec: meta/argument_specs.yml
# Validates parameters against meta/argument_specs.yml type contracts
- name: Provision database cluster
database_provision(role action) database_provisionRole EntrypointContract: meta/argument_specs.ymlProvisions high-availability database cluster instances with validation specs.Ctrl+B: Jump to meta/argument_specs.yml:
cluster_name(argument) cluster_name: strRequiredUnique name identifying the target database cluster group.: "prod-pg-cluster"
port(argument) port: intOptional • default: 5432Port on which the database instance listens for client queries.: 5432
engine(argument) engine: "postgres" | "mysql" | "mariadb"Required ChoiceDatabase engine type. Must strictly match declared choices: [...] list.Ctrl+Space: Trigger autocompletion for allowed choices: "postgres"
^? (argument) engine: "postgres" | "mysql" | "mariadb" = "postgres" (type checked ✓)
storage(argument) storage: { size_gb: int }Required DictStorage configuration dictionary requiring size_gb sub-option.:
size_gb: 250
Active Contract: meta/argument_specs.yml
port: type: int • default: 5432
engine: type: str • choices: ['postgres', 'mysql', 'mariadb']
storage: type: dict • required: ['size_gb']
✓ All 3 parameters strictly match argument_specs.yml
templates/nginx.conf.j2 • Split Preview Target:
AnsibleJinja Live Split View
# Jinja2 Template Source (with Twoslash fact hover)
worker_processes {{ ansible_processor_vcpus(fact) ansible_processor_vcpus: intDiscovered FactOrigin: ansible.builtin.setupDetected virtual CPU cores on target host. Resolves to 8 on active host context. }};
events {
worker_connections {{ (ansible_processor_vcpus * 1024) }};
}
http {
server {
listen {{ listen_port | default(filter) default(value, default_value=80, boolean=False)FilterIf the value is undefined, returns the passed default value; otherwise returns the variable's value.(80) }};
server_name {{ inventory_hostname(magic var) inventory_hostname: strAnsible MagicThe hostname/alias of the current host being evaluated in playbook loop. }};
}
}
# Live Rendered Output (Target: web-prod-01)
worker_processes 8;
events {
worker_connections 8192;
}
http {
server {
listen 443;
server_name web-prod-01;
}
}
^? Live synchronized with active host context variables & facts
roles/app/tasks/service.yml • Actions: Go to Definition (Ctrl+B) • Module Specs
Module Intelligence & Navigation
# Jump to role declarations or registered return values (Ctrl+B)
- name: Ensure application service is active
ansible.builtin.systemd_service(module) ansible.builtin.systemd_serviceCore ModuleCollection: ansible.builtinControls systemd units and services on remote Linux hosts. Supports state control, reload, enable, and mask operations.Ctrl+B: View module specification & documentation:
name(option) name: strRequiredName of the systemd unit / service to control.: "api-worker"
state(option) state: "started" | "stopped" | "restarted" | "reloaded"Optional ChoiceTarget running state for the specified service.: "started"
enabled: true
daemon_reload(option) daemon_reload: boolOptional • default: falseRun systemctl daemon-reload before applying unit state action.: true
register: app_service_result(registered var) app_service_result: RegisteredTaskResultTask Return StructScope: playbook tasksResult dictionary containing: changed: bool, status: dict, failed: bool, msg: str. Autocomplete available on all fields.Alt+F7: Find all usages of app_service_result
^? app_service_result: { changed: bool, status: dict, failed: bool } (module return schema)
- name: Include helper tasks
ansible.builtin.include_tasks(action) ansible.builtin.include_tasksCore ActionDynamically includes a file with a list of tasks. Allows direct navigation into included task lists.:
file: "handlers/notify.yml"(task include) handlers/notify.ymlFile ReferenceTarget task file in repository. Click or press Ctrl+B to navigate directly into the file.Ctrl+B: Jump to handlers/notify.yml
Navigation & Return Inspection

Core Capabilities

Engineered around authentic ansible-core evaluation semantics, built in pure Kotlin for the IntelliJ Platform.

1. Host Awareness & Context Switching

Switch target host context directly from the status bar widget or quick switcher to evaluate variables and tasks in their exact host environment.

  • Full inventory & group hierarchy resolution
  • Per-file scope inference for plays, roles, and group_vars
  • Molecule scenario & standalone role support

2. Variable Resolution & "Explain Precedence"

Computes effective variable values adhering to Ansible's full 22-step precedence order, with interactive breakdown cards and override tracing.

  • Hover inspection cards showing origin and data type
  • "Explain precedence" drill-down showing winning & overridden layers
  • Witness host analysis for conditionally undefined variables

3. Comprehensive Ansible Vault Integration

Transparent secret editing without leaving the IDE, designed with disk-protection safeguards preventing unencrypted files from hitting disk.

  • Inline vault reveal popup, rekey, and in-place edit
  • Whole-file vault tabs with automatic background sync protection
  • Static envelope linting (ANS-V101..ANS-V103) without requiring passwords

4. Role Argument Specs & Strict Type Checking

First-class support for meta/argument_specs.yml providing documentation hover cards, auto-completion, and static type checking.

  • Type validation for str, int, bool, list, dict, and path
  • Missing required sub-options detection (ANS-T002 / ANS-T003)
  • Choices mismatch inspection (ANS-T004) and undeclared input checks (ANS-S002)

5. Jinja2 Intelligence & YAML Language Injection

Dedicated file type for templates plus automatic Jinja2 expression injection into YAML template values and conditional directives.

  • Dedicated AnsibleJinja file type and syntax highlighting
  • YAML injection in when:, changed_when:, failed_when:, until:
  • Smart completion for variables, ansible_facts, item, filters, and tests

6. Live Template Split Preview

Live rendered split preview for Jinja2 templates (*.j2) rendered against the active host and playbook context.

  • In-editor split preview window updating as you type
  • Evaluates live against the active host's resolved facts and variables
  • Instant feedback for template loops and conditionals

7. Ansible Modules, Options & Keywords

Comprehensive module intelligence with built-in parameter specs, documentation tooltips, and static validation.

  • Hover tooltips for modules and playbook/task keywords
  • Smart completion for module parameters, choices, and boolean values
  • Module inspections for unknown options (ANS-M001) and missing options (ANS-M002)

8. Navigation, Find Usages & Refactoring

Full IDE navigation and refactoring tools tailored specifically to Ansible repository architecture.

  • Go to Definition (Ctrl+B) for variables, roles, task includes, and playbooks
  • Find Usages (Alt+F7) categorized into Read, Set, and Spec definitions
  • Safe rename refactoring across multi-role projects with reference updates

9. Dedicated Ansible Tool Window & Workspace Scopes

Structured repository tree explorer and live variable inspection window.

  • Explore environments, groups, hosts, playbooks, roles, and vars files
  • Effective variables table inspector for any selected host
  • Custom workspace scopes to filter inspections and views

Variable Precedence Engine

Ansible defines 22 levels of variable precedence. Ansibility implements the complete resolution graph in memory.

Precedence Resolution Hierarchy

When inspecting variables or rendering templates, Ansibility computes the exact winning definition among all active layers:

22
extra vars (-e / CLI)
18
block vars (tasks in block)
15
play vars / vars_files
12
inventory host_vars
07
inventory group_vars
04
role defaults (defaults/main.yml)

Host Scope Inference

Ansibility automatically infers which hosts each file applies to:

  • Playbooks: Inferred from hosts: declaration and inventory group membership.
  • Roles: Resolved through role dependencies (meta/main.yml) and playbook invocations.
  • group_vars / host_vars: Automatically mapped by filename and inventory tree structure.

Ansible Vault Security

Designed for safe everyday developer workflows with zero plaintext leaks.

Inline Vault Operations

Encrypted YAML values (!vault |) feature gutter lock icons for quick actions:

  • • Timed Reveal: Peek plaintext with automatic masking after 10s.
  • • In-Place Edit: Modify secret in a popup dialog and re-encrypt automatically.
  • • Rekey & Vault ID: Switch encryption keys without leaving the editor.

Safe Whole-File Vault Tabs

Open whole-file encrypted secrets directly in dedicated editor tabs. Background sync protection prevents unencrypted temporary files from being written to disk.

Static envelope linting verifies header formatting and block structure without requiring vault passwords.

Role Argument Specs & Diagnostics

Static analysis enforcing Ansible meta/argument_specs.yml contracts.

ANS-T001

Value Rejected by Spec: Flags parameter values that violate documented types or fail type coercion.

ANS-T002 / ANS-T003

Sub-option Validation: Detects missing required keys or undeclared options in dictionary specs.

ANS-T004

Choice Mismatch: Validates values against declared choices: [...] lists with completion.

ANS-V003

Witness Host Analysis: Identifies variables that are undefined on specific target hosts in the inventory.

IDE Compatibility

Ansibility is verified against JetBrains 2026.2+ IDE builds (build 262+).

PyCharm
Professional & Community
IntelliJ IDEA
Ultimate & Community
WebStorm
Complete Platform Support
PhpStorm
Complete Platform Support

Building from Source

Ansibility is written in Kotlin and built with Gradle.

bash — clone, build & run Shiki Highlighted
# Clone repository
git clone https://github.com/danielterletzkiy/ansibility.git
cd ansibility

# Build plugin ZIP distribution (plugin/build/distributions/)
./gradlew assemble

# Launch sandbox IDE with Ansibility pre-installed
./gradlew runIde