6. Inventory

6.1. What is Inventory?

  • Static lines of servers

  • Ranges

  • Other custom things (generated automatically)

  • Dynamic lists of servers: AWS, Azure, Google Cloud Platform, OpenStack

  • Special group: all

6.2. Static Inventory

  • Create file hosts

  • Default inventory file location /etc/ansible/hosts

  • If any other location, then specify ansible -i hosts ... for file named hosts, more info

  • Roles are defined in square brackets

  • Hosts are below roles

  • There are two default groups: all and ungrouped.

  • The all group contains every host.

  • The ungrouped group contains all hosts that don’t have another group aside from all

6.3. INI format

6.3.1. Simple list

Listing 93. cat hosts
[myhost]
127.0.0.1
Listing 94. cat hosts
[dbservers]
db01.example.com
db02.example.com

[appservers]
app01.example.com
app02.example.com
app03.example.com
[dc1]
db01.example.com
app01.example.com

[dc2]
db02.example.com

6.3.2. Range

Listing 95. Range
[myservers]
www[01:50].example.com

[databases]
db-[a:f].example.com
~(web|db).*\.example\.com

6.3.3. Host variables

[myservers]
host1 http_port=80 maxRequestsPerChild=808
host2 http_port=303 maxRequestsPerChild=909
[myservers]
localhost                ansible_connection=local
other1.example.com       ansible_connection=ssh        ansible_user=myuser
other2.example.com:2222  ansible_connection=ssh        ansible_user=myotheruser
some_host         ansible_port=2222     ansible_user=manager
aws_host          ansible_ssh_private_key_file=/home/example/.ssh/aws.pem
freebsd_host      ansible_python_interpreter=/usr/local/bin/python
ruby_module_host  ansible_ruby_interpreter=/usr/bin/ruby.1.9.3

6.3.4. Inventory aliases

  • In the above example, running Ansible against the host alias "jumper" will connect to 192.0.2.50 on port 5555.

  • This only works for hosts with static IPs, or when you are connecting through tunnels.

jumper ansible_port=5555 ansible_host=192.0.2.50

6.3.5. Group variables

[myservers]
host1
host2

[myservers:vars]
ntp_server=ntp.myhost.example.com
proxy=proxy.myhost.example.com
[db]
db[1:4]

[web]
web[1:4]

[east]
db1
web1
db3
web3

[west]
db2
web2
db4
web4

[dev]
db1
web1

[testing]
db3
web3

[prod]
db2
web2
db4
web4
[atlanta]
host1
host2

[raleigh]
host2
host3

[southeast:children]
atlanta
raleigh

[southeast:vars]
some_server=foo.southeast.example.com
halon_system_timeout=30
self_destruct_countdown=60
escape_pods=2

[usa:children]
southeast
northeast
southwest
northwest

6.4. YAML format

all:
  hosts:
    mail.example.com:
  children:
    myservers:
      hosts:
        foo.example.com:
        bar.example.com:
    databases:
      hosts:
        one.example.com:
        two.example.com:
        three.example.com:
all:
  hosts:
    mail.example.com:
  children:
    myservers:
      hosts:
        foo.example.com:
        bar.example.com:
    databases:
      hosts:
        one.example.com:
        two.example.com:
        three.example.com:
    dev:
      hosts:
        foo.example.com:
        one.example.com:
        two.example.com:
    test:
      hosts:
        bar.example.com:
        three.example.com:
    prod:
      hosts:
        foo.example.com:
        one.example.com:
        two.example.com:

6.4.1. Host variables

atlanta:
  host1:
    http_port: 80
    maxRequestsPerChild: 808
  host2:
    http_port: 303
    maxRequestsPerChild: 909

6.4.2. Inventory aliases

  • In the above example, running Ansible against the host alias “jumper” will connect to 192.0.2.50 on port 5555.

  • This only works for hosts with static IPs, or when you are connecting through tunnels.

...
  hosts:
    jumper:
      ansible_port: 5555
      ansible_host: 192.0.2.50

6.4.3. Group variables

myservers:
  hosts:
    host1:
    host2:
  vars:
    ntp_server: ntp.myhost.example.com
    proxy: proxy.myhost.example.com

6.5. Files

  • You can store variables in the main inventory file

  • Storing separate host and group variables files may help you organize your variable values more easily

  • Host and group variable files must use YAML syntax

  • Valid file extensions include .yml, .yaml, .json, or no file extension.

  • Ansible loads host and group variable files by searching paths relative to the inventory file or the playbook file

  • If your inventory file at /etc/ansible/hosts contains a host named ‘foosball’ that belongs to two groups, raleigh and webservers, that host will use variables in YAML files at the following locations:

Listing 96. Filenames can optionally end in .yml, .yaml, or .json
/etc/ansible/group_vars/raleigh
/etc/ansible/group_vars/webservers
/etc/ansible/host_vars/foosball
ntp_server: acme.example.org
database_server: storage.example.org
  • You can also add group_vars/ and host_vars/ directories to your playbook directory

  • The ansible-playbook command looks for these directories in the current working directory by default

  • Other Ansible commands (for example, ansible, ansible-console, etc.) will only look for group_vars/ and host_vars/ in the inventory directory

  • If you want other commands to load group and host variables from a playbook directory, you must provide the --playbook-dir option on the command line

  • If you load inventory files from both the playbook directory and the inventory directory, variables in the playbook directory will override variables set in the inventory directory

6.6. Docker

- name: create jenkins container
  docker_container:
    docker_host: myserver.net:4243
    name: my_jenkins
    image: jenkins

- name: add container to inventory
  add_host:
    name: my_jenkins
    ansible_connection: docker
    ansible_docker_extra_args: "--tlsverify --tlscacert=/path/to/ca.pem --tlscert=/path/to/client-cert.pem --tlskey=/path/to/client-key.pem -H=tcp://myserver.net:4243"
    ansible_user: jenkins
  changed_when: false

- name: create directory for ssh keys
  delegate_to: my_jenkins
  file:
    path: "/var/jenkins_home/.ssh/jupiter"
    state: directory

6.7. Best Practices

  • Give inventory nodes human-meaningful names rather than IPs or DNS hostnames

  • If you change inventory file frequently (one or two times a month) use dynamic inventory files

  • If it's a static environment (new servers are added rarely) use static inventory

  • Dynamic inventory files are quite easy