Related docs:
INVENTORY PLUGIN INVENTORY CAPABILITIES IDM VAULT USE CASES DOCS MAP
This page contains worked examples for eigenstate.ipa.idm.
Use the capability guide to choose the IdM object class. Use this page when you need the corresponding inventory files and playbook targets.
Not every caller is an IdM administrator. A delegated operator can use this collection inside their own jurisdiction as long as the principal they run under can read the hosts, hostgroups, netgroups, or HBAC rules that matter to that scope.
flowchart LR
question["Operational question"] --> source["Choose IdM source"]
source --> inventory["Render Ansible inventory"]
inventory --> run["Target hosts by role,\naccess boundary, or policy"]
All examples assume an IdM domain corp.example.com with these patterns:
web-01, web-02, web-03 in a webservers hostgroupdb-01, db-02 in a databases hostgroupall-app-servers hostgroup containing webservers and databasesops-admin-access and developer-access netgroupsallow_all, allow_ssh_ops, and allow_ssh_devs HBAC rulesWhen the job must run against every enrolled system, use hosts.
flowchart LR
H["All IdM hosts"] --> I["sources: [hosts]"] --> T["compliance scan on entire estate"]
Inventory:
plugin: eigenstate.ipa.idm
server: idm-01.corp.example.com
ipaadmin_password: "{{ lookup('env', 'IPA_ADMIN_PASSWORD') }}"
verify: /etc/ipa/ca.crt
sources:
- hosts
compose:
ansible_host: idm_fqdn
Playbook target:
- name: Quarterly compliance scan
hosts: all
tasks:
- ansible.builtin.command:
cmd: oscap xccdf eval --profile stig /usr/share/xml/scap/content.xml
failed_when: false
Kerberos is especially profitable here when the scan runner lives in AAP or a shared automation account:
kinitWhen IdM hostgroups already define the runtime role boundary, use hostgroups.
flowchart LR
HG["webservers + databases"] --> I["sources: [hosts, hostgroups]"] --> T["role-specific deploys"]
Inventory:
plugin: eigenstate.ipa.idm
server: idm-01.corp.example.com
ipaadmin_password: "{{ lookup('env', 'IPA_ADMIN_PASSWORD') }}"
verify: /etc/ipa/ca.crt
sources:
- hosts
- hostgroups
hostgroup_filter:
- webservers
- databases
host_filter_from_groups: true
compose:
ansible_host: idm_fqdn
Playbook target:
- name: Deploy frontend config
hosts: idm_hostgroup_webservers
tasks:
- ansible.builtin.template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
- name: Restart database tier
hosts: idm_hostgroup_databases
tasks:
- ansible.builtin.service:
name: postgresql
state: restarted
This is also a good delegated-operator pattern. The caller does not need global IdM admin rights if their principal is allowed to read the hostgroups for their team or business unit.
When the meaningful role boundary is a nested hostgroup, let the plugin resolve it.
flowchart LR
HG["all-app-servers\nnested hostgroup"] --> I["resolved group membership"] --> T["single maintenance tier"]
Inventory:
plugin: eigenstate.ipa.idm
server: idm-01.corp.example.com
ipaadmin_password: "{{ lookup('env', 'IPA_ADMIN_PASSWORD') }}"
verify: /etc/ipa/ca.crt
sources:
- hosts
- hostgroups
hostgroup_filter:
- all-app-servers
host_filter_from_groups: true
Playbook target:
- name: Rolling application-tier patch window
hosts: idm_hostgroup_all_app_servers
serial: 2
tasks:
- ansible.builtin.dnf:
name: "*"
state: latest
Delegated operators often use this pattern for their own service slice because the parent hostgroup already defines the boundary they are responsible for.
When IdM metadata is useful but there is no explicit hostgroup for it, keep
hosts and derive groups with keyed_groups.
flowchart LR
M["idm_location / idm_os"] --> G["keyed_groups"] --> T["target by metadata"]
Inventory:
plugin: eigenstate.ipa.idm
server: idm-01.corp.example.com
ipaadmin_password: "{{ lookup('env', 'IPA_ADMIN_PASSWORD') }}"
verify: /etc/ipa/ca.crt
sources:
- hosts
keyed_groups:
- key: idm_location
prefix: dc
separator: "_"
- key: idm_os
prefix: os
separator: "_"
Playbook target:
- name: Patch east datacenter first
hosts: dc_DC_East
serial: 2
tasks:
- ansible.builtin.dnf:
name: "*"
state: latest
Kerberos pays off here because it lets a non-admin operator run the same inventory source repeatedly from AAP or a bastion without storing a password in the playbook.
When Automation Controller only needs a small metadata surface for smart
inventories or grouped targeting, keep the inventory plugin on hosts and
trim the exported idm_* variables.
flowchart LR
IDM["IdM hosts"] --> INV["sources: [hosts]"]
INV --> FILTER["hostvars_include"]
FILTER --> AAP["lean synced inventory"]
Inventory:
plugin: eigenstate.ipa.idm
server: idm-01.corp.example.com
use_kerberos: true
kerberos_keytab: /runner/env/ipa/admin.keytab
verify: /etc/ipa/ca.crt
sources:
- hosts
hostvars_include:
- idm_location
- idm_os
- idm_hostgroups
keyed_groups:
- key: idm_location
prefix: dc
separator: "_"
Why this helps:
When the question is who can reach the systems, use netgroups.
flowchart LR
NG["ops-admin-access"] --> I["sources: [hosts, netgroups]"] --> T["access-scope audit"]
Inventory:
plugin: eigenstate.ipa.idm
server: idm-01.corp.example.com
ipaadmin_password: "{{ lookup('env', 'IPA_ADMIN_PASSWORD') }}"
verify: /etc/ipa/ca.crt
sources:
- hosts
- netgroups
netgroup_filter:
- ops-admin-access
host_filter_from_groups: true
Playbook target:
- name: Record operations access scope
hosts: idm_netgroup_ops_admin_access
tasks:
- ansible.builtin.lineinfile:
path: /tmp/ops_access_hosts.txt
line: "{{ idm_fqdn }} - {{ idm_location }}"
create: true
delegate_to: localhost
This is not a global-admin task. It is a jurisdictional audit task: a delegated operator can inspect the hosts their team may touch without needing broader IdM privileges.
When the target boundary is the policy itself, use HBAC rules.
flowchart LR
HB["allow_ssh_ops"] --> I["sources: [hosts, hbacrules]"] --> T["policy-scoped hardening"]
Inventory:
plugin: eigenstate.ipa.idm
server: idm-01.corp.example.com
ipaadmin_password: "{{ lookup('env', 'IPA_ADMIN_PASSWORD') }}"
verify: /etc/ipa/ca.crt
sources:
- hosts
- hbacrules
hbacrule_filter:
- allow_ssh_ops
host_filter_from_groups: true
Playbook target:
- name: Harden SSH on systems in the ops SSH policy boundary
hosts: idm_hbacrule_allow_ssh_ops
tasks:
- ansible.builtin.template:
src: sshd_config_hardened.j2
dest: /etc/ssh/sshd_config
validate: sshd -t -f %s
For non-admin teams, this is the common pattern: the HBAC rule already encodes the scope they are allowed to manage, and the collection simply turns that policy into a target set.
When an HBAC rule uses hostcategory=all, the group becomes an easy audit and
validation boundary.
flowchart LR
HB["allow_all\nhostcategory=all"] --> I["expands to every host"] --> T["policy coverage check"]
Inventory:
plugin: eigenstate.ipa.idm
server: idm-01.corp.example.com
ipaadmin_password: "{{ lookup('env', 'IPA_ADMIN_PASSWORD') }}"
verify: /etc/ipa/ca.crt
sources:
- hosts
- hbacrules
hbacrule_filter:
- allow_all
Playbook target:
- name: Ensure monitoring agent is present on all policy-covered systems
hosts: idm_hbacrule_allow_all
tasks:
- ansible.builtin.package:
name: insights-client
state: present
Kerberos is especially useful for delegated inventory work because:
kerberos_keytab for non-interactive
authUse password auth only when you do not have a service principal or a keytab workflow available.
For the decision model behind these scenarios, return to INVENTORY CAPABILITIES.