Hello!

Today I will show you what inventory in Ansible and how to use them.

Ansible has two types of inventory - static and dynamic. Static is used when we know in advance the list of servers on which Ansible should run. And dynamic when we do not have this data in advance and we want to receive it dynamically.

Static inventory

To use static inventory, it is enough to simply create a file, for example, inventory, and inside you can specify IP addresses, for example:

192.168.1.1

This can be used immediately by specifying this file in the ansible command using -i inventory all. all means to run ansible on all servers from the inventory file.

$ ansible -m ping -i inventory all --private-key SSH_KEY --user SSH_USER
192.168.1.1 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}

Servers can also be combined into groups.

[web]
192.168.1.1

[database]
192.168.1.1

And now you can run ansible only for some group. To do this, you need to specify the name of the group instead of all. If you need to run for all servers, you can specify all again.

$ ansible -m ping -i inventory web --private-key SSH_KEY --user SSH_USER
192.168.1.1 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}

You can also specify a set of parameters for each server or group in the inventory. For example, the value that we passed using the –user key can be specified in the inventory.

[web]
192.168.1.1 ansible_user=centos

Now the –user key can be omitted

$ ansible -m ping -i inventory web --private-key SSH_KEY
192.168.1.1 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}

Also, parameters can be set at the group level, for this, you need to add another group with a name like[GROUP_NAME:vars]

[web]
192.168.1.1

[web:vars]
ansible_user=centos

The result will be the same as in the previous version, only now these parameters will be applied to this group.

Any values that will be used in playbooks in the future can be passed as parameters.

Also, several groups can be added to one group.

[web]
192.168.1.1

[db]
192.168.1.2

[webdb:children]
web
db

And if I specify -i inventory webdb when running ansible, ansible will run for all servers from those two groups.

Group Vars

Inventory is not the best place to store parameters. It is better to create a folder called group_vars and organize parameters for each group in it. The group can be organized as a folder or a file. In this example, I created a folder with a name that corresponds to the name of the group and inside a file that can have any name.

tree group_vars
group_vars
└── web
    └── web

In file web now i can add variables which will be used for group web

ansible_user: centos

And if I run ansible, I get the same result as last time.

Dynamic Inventory

Dynamic inventory is needed if we do not know the IP addresses in advance. For example, with AWS, where servers can often change and have different IP addresses. Dynamic inventory is a script that is passed to the -i parameter, and when this script is run, I will get all the necessary information about the servers. Some dynamic inventories have become part of ansible and do not need to be downloaded additionally, it is enough to simply indicate that it needs to be used.

To use AWS dynamic inventory, you need to install an additional python library called boto3. It can be installed using pip install boto3.

Since AWS dynamic inventory is part of ansible, no scripts need to be downloaded. But you need to create a configuration file aws_ec2.yml. The simplest one will look like this. And specify this file with -i key

plugin: aws_ec2
regions:
  - REGION
boto_profile: AWS_PROFILE

In this case, ansible will be launched on all servers that are in this AWS account in the specified region. You can use filters to filter only the servers you want. For example, only servers that have the type = database tag.

plugin: aws_ec2
regions:
  - REGION
boto_profile: AWS_PROFILE
filters:
  tag:type: database

Filters can be combined. All possible options can be found in the documentation of a specific dynamic plugin(AWS docs).

Video