如何在Ansible中判断已注册主机变量所属库存组并输出?
Got it, let's tackle this Heartbeat configuration issue you're facing. I've dealt with similar requirements where we needed to tag monitors with inventory groups for Kibana filtering, so here's how to make it work:
Step 1: Preprocess Target Hosts with Their Inventory Groups
First, we need to build a list of your target hosts along with their associated inventory groups. We'll use Ansible's built-in hostvars and groups variables to pull this info, and filter out any hosts that aren't present in your inventory.
Add this task to your role's tasks/main.yml:
- name: Build list of target hosts with their inventory groups set_fact: heartbeat_targets: > {% set processed_hosts = [] %} {% for host in your_target_hosts_variable %} {% if host in groups['all'] %} {% do processed_hosts.append({ 'hostname': host, 'inventory_groups': hostvars[host]['group_names'] }) %} {% endif %} {% endfor %} {{ processed_hosts }}
- Replace
your_target_hosts_variablewith the actual variable holding your list of target hosts (the "已注册的主机名变量" you mentioned). - This task checks if each target host exists in the inventory (
groups['all']), then grabs all its assigned groups viahostvars[host]['group_names'], and stores everything in a structured list.
Step 2: Update Your Jinja Template to Use the Processed Data
Now modify your icmp.yml.j2 template to loop through the heartbeat_targets variable and inject the group info into each monitor's configuration.
If you're creating a separate monitor for each host (as you mentioned "独立配置文件"), use this template structure:
heartbeat.monitors: {% for target in heartbeat_targets %} - type: icmp schedule: '*/5 * * * * *' hosts: ["{{ target.hostname }}"] name: "ICMP Ping - {{ target.hostname }}" fields: # Add groups as a comma-separated string for easy Kibana filtering target_groups: "{{ target.inventory_groups | join(',') }}" # Or keep as a list if you prefer array format in Elasticsearch # target_groups: {{ target.inventory_groups }} {% endfor %}
- The
fields.target_groupswill now hold all inventory groups the target host belongs to, which you can use in Kibana to filter monitor results by group. - Adjust the
scheduleand other monitor settings to match your needs.
Key Notes to Keep in Mind
- Fact Collection: Ensure Ansible has collected facts for your target hosts, or at least that their group information is available in
hostvars. If you haven't rungather_facts, you can still accessgroup_namessince it's an inventory variable (no need for full fact collection). - Filtering Invalid Hosts: The
if host in groups['all']check skips any hosts that aren't in your inventory, preventing errors from trying to accesshostvarsfor non-existent hosts. - Group Format: Using
join(',')converts the list of groups into a string, which is often easier to work with in Kibana's filter bar. If you want to keep groups as an array in Elasticsearch, omit thejoinfilter.
Example Output
Suppose your inventory has:
[web_servers] web01.example.com web02.example.com [db_servers] db01.example.com
And your_target_hosts_variable is ['web01.example.com', 'db01.example.com'], the generated heartbeat_targets list will look like:
[ {"hostname": "web01.example.com", "inventory_groups": ["web_servers", "all"]}, {"hostname": "db01.example.com", "inventory_groups": ["db_servers", "all"]} ]
Your final icmp.yml will have two monitors, each with target_groups set to web_servers,all and db_servers,all respectively.
内容的提问来源于stack exchange,提问作者Tomusz

