Skip to content

Build Status


Lab 002 - No Inventory

  • In this lab we will learn about Ansible inventory and how it affects automation tasks.
  • We will start with an empty inventory and observe Ansible’s behavior with no hosts defined. Later, we will create and test the inventory file.
  • This lab is based upon the previous lab and its docker-compose setup.

Pre-Requirements

  • Complete the previous lab in order to have Ansible configured.

01. “Clear” the inventory

  • Let’s clear the inventory from previous labs and walk through what is inventory.

02. Create the inventory file

Ansible Inventory

  • An Ansible inventory can either be a single file or a collection of files
  • The inventory defines the [hosts] and [groups] of hosts upon which Ansible will operate.
  • It’s simply a list of servers that Ansible can connect with and manage.

Key features of Ansible inventory

  • Can be in various formats, such as INI, JSON, YAML and more.
  • YAML being the most common format.
  • inventory defines the target hosts for playbook execution.
  • inventory organizes hosts into logical groups for easier management.
  • inventory can store host-specific variables and group variables.
  • inventory supports nested groups (groups of groups).

03. inventory samples

  • INI format

    [webservers]
    web1.example.com
    web2.example.com
    
    [database]
    db1.example.com
    

  • YAML format

    all:
        hosts:
            web1.example.com:
            web2.example.com:
        children:
            database:
            hosts:
                db1.example.com:
    

  • JSON format

    {
    "all": {
        "hosts": {
        "web1.example.com": {
            "ansible_port": 2222,
            "http_port": 80
        },
        "web2.example.com": {
            "ansible_port": 2223,
            "http_port": 8080
        }
        },
        "children": {
        "database": {
            "hosts": [
            "db1.example.com"
            ]
          }
        }
      }
    }
    


Inventory types in Ansible

  1. Static Inventory

    • This is generally a simple text file (usually in INI or YAML format) that lists the hosts and their corresponding groups.
  2. Dynamic Inventory

    • This is generated by a script or a program that retrieves host information from an external source (such as cloud providers like AWS, Azure, etc.), LDAP or from a database.
    • This allows for real-time updates and adaptability as environments change.

    See an example of generating a dynamic inventory using Python code for fetching data from a database:

    ```python
    #!/usr/bin/env python
    import sqlite3
    import json
    
    def get_inventory():
        conn = sqlite3.connect('servers.db')
        cursor = conn.cursor()
    
        cursor.execute('SELECT hostname, group_name, ansible_user FROM servers')
        rows = cursor.fetchall()
    
        inventory = {'all': {'hosts': [], 'vars': {}}}
    
        for row in rows:
            hostname, group_name, ansible_user = row
    
            if group_name not in inventory:
                inventory[group_name] = {'hosts': [], 'vars': {}}
    
            inventory['all']['hosts'].append(hostname)
            inventory[group_name]['hosts'].append(hostname)
            inventory[group_name]['vars']['ansible_user'] = ansible_user
    
        conn.close()
        return inventory
    
    if __name__ == "__main__":
        print(json.dumps(get_inventory()))
    ```
    

04. Lab exercise

  • Let’s create the inventory configuration that we will use for the labs:

    ### File location: $RUNTIME_FOLDER/labs-scripts/inventory
    ###
    ### List of servers which we want Ansible to connect to
    ### The names are defined in the docker-compose
    ###
    
    [servers]
    # No server will be defined at this step
    

05. No inventory invocation

  • Once all is ready, let’s check if the controller can connect to the servers using ping

    # Ping the servers and check that they are "alive"
    docker exec ansible-controller sh -c "cd /labs-scripts && ansible all -m ping"
    
    ## Output
    ## -------------------------------------------------------------------------------
    [WARNING]: provided hosts list is empty, only localhost is available. Note that
    the implicit localhost does not match 'all'
    

06. inventory invocation

  • Fill in the inventory based upon the previous labs’ configuration and test it.
  • Verify that the inventory is defined correctly with:
    ansible-inventory -i <inventory_file> --graph
    
  • Test the inventory file with
    ansible -i <inventory_file> -m ping
    
  • Suggested Solution

    ###
    ### List of servers which we want ansible to connect to
    ### The names are defined in the docker-compose
    ###
    
    [servers]
      linux-server-1 ansible_ssh_common_args='-o UserKnownHostsFile=/root/.ssh/known_hosts'
      linux-server-2 ansible_ssh_common_args='-o UserKnownHostsFile=/root/.ssh/known_hosts'
      linux-server-3 ansible_ssh_common_args='-o UserKnownHostsFile=/root/.ssh/known_hosts'