In an ansible host(or inventory) file, you can group host using brackets. I want to sort these groups using sort function in linux but it will sort the individual hosts, and I want the right host to still be under the correct group. For example,
[webservers]
examplehostserver
hostname3
[database]
db_server_1
local_db_server
[ExampleGroup]
Server05
Myserver01
I'm looking for a way to sort by group while keeping the host under the correct group
I have a feeling this is not possible within terminal commands or bash
Simple bash script
#!/bin/bash
hosts_file=$1
sections=$(cat $hosts_file | grep "\[" | tr -d "[]" | sort)
for i in $sections; do
sed -n -e "/\[$i\]/,/\[/p" $hosts_file | sed '${/\[.*/d}'
done
with larsks' input gives
[database]
db_server_1
local_db_server
[ExampleGroup]
Server05
Myserver01
[webservers]
examplehostserver ansible_host=10.0.0.1
hostname3
[webservers:vars]
apache_package_name=httpd
Native Ansible solution is limited to the groups and hosts. The play below with the example inventory from the question
tasks:
- debug:
msg: "{{ item }}:{{ groups[item] }}"
loop: "{{ groups.keys()|difference(['all', 'ungrouped'])|sort }}"
gives (abridged):
"msg": "database:[u'db_server_1', u'local_db_server']"
"msg": "ExampleGroup:[u'Server05', u'Myserver01']"
"msg": "webservers:[u'examplehostserver', u'hostname3']"
and the same loop with blockinfile
tasks:
- blockinfile:
create: yes
path: "{{ playbook_dir }}/my_hosts"
block: |
[{{ item }}]
{% for host in groups[item] %}
{{ host }}
{% endfor %}
marker: "# {mark} group:{{ item }}"
loop: "{{ groups.keys()|difference(['all', 'ungrouped'])|sort }}"
creates file:
> cat my_hosts
# BEGIN group:database
[database]
db_server_1
local_db_server
# END group:database
# BEGIN group:ExampleGroup
[ExampleGroup]
Server05
Myserver01
# END group:ExampleGroup
# BEGIN group:webservers
[webservers]
examplehostserver
hostname3
# END group:webservers
Reconstruction of the inventory from the Ansible variables that would comprise a declaration of variables would not be unambiguous.
You could do it with a simple Python script:
#!/usr/bin/python
import sys
groups = {}
group = None
for line in sys.stdin:
line = line.rstrip()
if line.startswith('['): # look for inventory groups
group = line[1:-1].lower() # extract the group name
groups[group] = []
if group and line: # gather up non-blank lines
groups[group].append(line)
for group in sorted(groups): # sort groups by name
print('\n'.join(groups[group])) # print out the group
print()
Assuming that we have your example inventory in the file hosts
, and the above script in sortinv.py
, the following command:
python sortinv.py < hosts
Produces:
[database]
db_server_1
local_db_server
[ExampleGroup]
Server05
Myserver01
[webservers]
examplehostserver
hostname3
The advantage of this mechanism is that it will preserve things like host variables and group variables. For example, given this input:
[webservers]
examplehostserver ansible_host=10.0.0.1
hostname3
[database]
db_server_1
local_db_server
[ExampleGroup]
Server05
Myserver01
[webservers:vars]
apache_package_name=httpd
We get:
[database]
db_server_1
local_db_server
[ExampleGroup]
Server05
Myserver01
[webservers]
examplehostserver ansible_host=10.0.0.1
hostname3
[webservers:vars]
apache_package_name=httpd
Much of that additional data would be lost by Vladimir's solution.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.