1 The basic idea of "inventory"
An inventory is a way to organize managed servers so Ansible can determine against which servers to run a play.
In a word, an inventory is used by Ansible to find server names to operate. Without an inventory, every ansible command has to have target server names as arguments. When more than 3 servers are targeted, it becomes ugly to do so.
ansible "server1,server2,server3,server4" .....
To make it simple, an inventory put multiple servers into a group, so that the above becomes:
ansible group1 .....
Of course, inventory has many other facilities besides grouping.
The default inventory file is /etc/ansible/hosts, while ansible/ansible-playbook has -i option to override this.
Tips: use the "--list-hosts" option to list the managed nodes targeted without actually running any commands. e.g. "ansible all --list-hosts"
Tips: use the "--list-hosts" option to list the managed nodes targeted without actually running any commands. e.g. "ansible all --list-hosts"
2 Group
Grouping is the most fundamental part of an inventory.
[group1]
server1
server2
server3
A group contains any number of servers; at the same time, a server can belong to any number of groups. The idea behind it is you can organize a server based on different standards, like OS type, function, etc. In the example below, server1 belongs to both groups "webservers" and "centos".
[webservers]
server1
server2
server3
[dbservers]
server4
[centos]
server1
server2
[ubuntu]
server3
server4
Groups can also be nested, which means a group can contain other groups as well. In the example below, the group "linux" contains group "centos" and group "ubuntu".
[linux:children]
centos
ubuntu
A group can not contain hosts and subgroups in one place, as it doesn't know if the member is a host or a subgroup.
A group can not contain hosts and subgroups in one place, as it doesn't know if the member is a host or a subgroup.
[group1]
host11
host12
host12
[group2:children]
group1
host21 # This is an error
The right way is to separate its definition.
[group1]
host21 # This is an error
The right way is to separate its definition.
[group1]
host11
host12
host12
[group2:children]
group1
[group2]
host21
[group2]
host21
Groups can not be overridden. If a group has been defined multiple times, all members are unioned. In the following example, group1 contains both "db.example.com" and "test.example.com".
[group1]
db.example.com
[group1]
test.exmaple.com
3 Pre-defined groups/hosts
In addition to user-defined groups, an inventory has built-in groups.
- all
All hosts defined in an inventory file belong to the built-in group "all". This makes sure that every host at least belongs to one group.
$ cat ./hosts
server1
server2
If a server is not added into a group explicitly, it belongs to the group 'all'. In the above example, server1 and server2 belong to "all".
- localhost
"localhost" is a predefined host that doesn't belong to any group (even "all") by default. This makes sure there is at least one available managed node as soon as Ansible is installed.
$ ansible localhost --list-hosts
hosts (1):
localhost
4 Inventory variables
Inventories also support variables that are defined for a server or a group.
[group1]
server0 ansible_user=user01
server1
[group1:vars]
ansible_user=user02
Generally speaking, defining variables in an inventory file is not recommended.
Another way to define inventory variables is "inventory variable files" which are files with special names and paths, like "host_vars/server0", "group_vars/group1". I am not going to discuss this right now.
It's much more common to use "playbook variables" than "inventory variables" in the real world.
5 Dynamic inventory
Until now, all the inventories we have seen in this article are static files, which are there before running any ansible commands.
Ansible also supports "dynamic inventories" which are generated on the fly. Do you remember the "--inventory" or "-i" option? the argument for it can be a static file but also can be an executable file too.
ansible -i test.sh all --list-hosts
Of course test.sh must print contents that are in the right format so ansible can parse it as inventory.
The following is a very simple example of test.sh.
$ cat test.sh
#!/bin/bash
echo '{"group": { "hosts": ["server1"] } }'
We can check the result by:
$ ansible -i test.sh all --list-hosts
hosts (1):
server1
The main purpose of dynamic inventories is to configure auto-scaling servers from Cloud where the actually running server list keeps changing automatically based on the current workload.
Most Cloud provider provides API to get the server list provisioned. And a dynamic inventory can be a script utilizing the API provided.
6 multiple inventories
Actually, the "--inventory" option can also be a directory, if so, ansible will evaluate every file inside that directory as a static or dynamic inventory.
ansible all -i inventory_dir --list-hosts
Note: Please keep the inventory_dir folder to only contain inventories.
Both the ansible command line and playbooks use "patterns" to select targeted hosts from inventories.
ansible <host-pattern> [options]
"<host-pattern>" is very flexible. It could be one of :
The patterns can be very complex, however, in the real world, most cases are simple.
Before actually run playbooks or tasks, use '--list-hosts' to check targeted nodes is a good idea.
7 Patterns: selecting hosts from an inventory
Inventories are where managed nodes are listed in an organized way. Ansible uses "patterns" to select hosts to run tasks.Both the ansible command line and playbooks use "patterns" to select targeted hosts from inventories.
ansible <host-pattern> [options]
"<host-pattern>" is very flexible. It could be one of :
- a host
- a group
- multiple hosts
- multiple groups
- a mix of hosts and groups
- wildcard patterns
- regex
- group position
Examples:
inventory file - hosts:
[web]
www1
www2
[db]
db1
db2
[centos]
www1
db1
[win2016]
www2
db2
$ ansible -i hosts --list-hosts www1
hosts (1):
www1
$ ansible -i hosts --list-hosts db
hosts (2):
db1
db2
$ ansible -i hosts --list-hosts www1,db1
hosts (2):
www1
db1
$ ansible -i hosts --list-hosts www1:db1
hosts (2):
www1
db1
$ ansible -i hosts --list-hosts www1,db
hosts (3):
www1
db1
db2
$ ansible -i hosts --list-hosts 'www*'
hosts (2):
www1
www2
$ ansible -i hosts --list-hosts 'www?'
hosts (2):
www1
www2
$ ansible -i hosts --list-hosts 'w*'
hosts (3):
www1
www2
db2
$ ansible -i hosts --list-hosts 'web:!centos'
hosts (1):
www2
$ ansible -i hosts --list-hosts 'web:¢os'
hosts (1):
www1
$ ansible -i hosts --list-hosts '~(www|db)1'
hosts (2):
www1
db1
Before actually run playbooks or tasks, use '--list-hosts' to check targeted nodes is a good idea.
No comments:
Post a Comment