Ansible playbook: load internal inventory file while running
Asked Answered
E

4

9

I hava an inventory file in INI format:

for example:

[db]
8.8.8.8 ansible_user=root ansible_ssh_private_key_file=/keys/root-id_rsa.pem
....

I'm looking for a way to automatically load my inventory file while running without specify which inventory file path when I triggered my ansible-playbook command

ansible-playbook playbook.yml --inventory-file=hosts (I'm trying to avoid from this) -vv

I'm familiar with the "add_host" module but still I prefer to create an inventory file in INI format and somehow to let the playbook load it automatically. is that possible?

Edit:

Thanks to the users @techraf and @Jeff Hemmen I added more details to question

In addition, I don't want to use either the ansible.cfg file because I want to perform this inside the playbook.yml file itself and not from outside

something like:

- name: add_host {{environment_type}} db servers
  hosts: localhost
  vars_files:
     - vars/main.yml
  roles:
       - { role: my_role}
  inventory_file: (possible?)
     - inventory/hosts.ini (possible?)
Eighteen answered 7/11, 2017 at 13:46 Comment(1)
Possible this partially answers your question: #29003920Tightrope
S
2

I want to perform this inside the playbook.yml file itself and not from outside

You cannot set an inventory file inside the playbook. Playbook is a list of plays and plays must have hosts declaration. There is no way to refer from inside the playbook to the inventory before Ansible tries (and fails to) interpret hosts.

Specify inventory in the ansible.cfg file stored in the same directory as your playbook:

[defaults]
inventory = ./hosts
Synchroscope answered 7/11, 2017 at 13:52 Comment(2)
thank you very much for your answer but I want to do this inside the play book without configure or edit any other file outside of my ansible hierarchy . I will add this remark to my postEighteen
that's why I'm asking here if this is possible.Eighteen
E
1

In your ansible.cfg, in the [defaults] section, there is a directive called inventory. Set that to your inventory file or directory.

Mine reads:

...
[defaults]

# some basic default values...

inventory      = inventory/
...
Electro answered 7/11, 2017 at 13:53 Comment(2)
thank you very much for your answer but I want to do this inside the play book without configure or edit any other file outside of my ansible hierarchy . I will add this remark to my postEighteen
ansible.cfg is inside your ansible hierarchy, at the root of it :)Electro
P
0

There are many possibilities. First would be using ansible plugins for static and/or dynamic inventory loading/configuration. For couple of built-in examples you can refer to the ansible documentation - as listed bellow. You can call them inside your play at any time same as mostly all ansible plugins:

  1. ansible.builtin.[plugin_name]:

    • ansible.builtin.advanced_host_list – Parses a ‘host list’ with ranges
    • ansible.builtin.constructed – Uses Jinja2 to construct vars and groups based on existing inventory.
    • ansible.builtin.generator – Uses Jinja2 to construct hosts and groups from patterns
    • ansible.builtin.host_list – Parses a ‘host list’ string
    • ansible.builtin.ini – Uses an Ansible INI file as inventory source.
    • ansible.builtin.script – Executes an inventory script that returns JSON
    • ansible.builtin.toml – Uses a specific TOML file as an inventory source.
    • ansible.builtin.yaml – Uses a specific YAML file as an inventory source

    or for more complex and fully dynamic inventory generation go to:

  2. amazon.aws.aws_ec2_inventory:

    To install it, use: ansible-galaxy collection install amazon.aws. You need further requirements to be able to use this inventory plugin, see Requirements for details.

    To use it in a playbook, specify: amazon.aws.aws_ec2.

    • amazon.aws.aws_ec2 - Get inventory hosts from Amazon Web Services EC2. Uses a YAML configuration file that ends with aws_ec2.{yml|yaml}.
  3. ansible.builtin.add_host:

    • Use variables to create new hosts and groups in inventory for use in later plays of the same playbook.

    • Takes variables so you can define the new hosts more fully.

    • This module is also supported for Windows targets.

    Using this module you can loop your custom list/dictionary with strings that should be converted to hosts. Full playbook example bellow:

    - name: 'Parse dictionary hosts'
      hosts: 'localhost'
      vars:
        my_parsed_hosts:
          controller-a:
            name: 'controller-node'
            ansible_user: 'ubuntu'
            ansible_host: '10.0.10.1'
            my_variable: false
          worker-b:
            name: 'worker-node'
            ansible_user: 'ubuntu'
            ansible_host: '127.0.0.1'
            my_variable: false
          aws-worker-custom-c:
            name: 'aws-worker-custom'
            ansible_user: 'ubuntu'
            ansible_host: '192.168.42.128'
            my_variable: true
      tasks:
        - name: 'Add new hosts to this playbook from dictionary'
          ansible.builtin.add_host:
            name: '{{ item.value.name }}'
            ansible_user: '{{ item.value.ansible_user }}'
            ansible_host: '{{ item.value.ansible_host }}'
            my_variable: '{{ item.value.my_variable }}'
            groups:
              - 'worker_nodes'
              - 'grafana'
          with_dict: '{{ my_parsed_hosts }}'
          when:
            - ('worker_nodes' not in groups)
            - ('worker' in item.value.name)
            - (item.value.name not in ansible_play_hosts_all)
    
    - name: 'Use parsed dictionary hosts'
      hosts: 'worker_nodes'
      tasks:
        - name: 'Print debug welcome message'
          ansible.builtin.debug:
            msg: >
              Node {{ ansible_host }} says welcome!
    
Pren answered 5/2, 2023 at 11:23 Comment(1)
Can you also give an example for item 1? "You can call them inside your play at any time same as mostly all ansible plugins". How do you use ansible.builtin.yaml to load a yaml inventory file inside your playbook?Classify
O
-1

this is easy, make the playbook call another playbook with shell:

Shell: ansible-playbook -i inventory.ini yourplaybook.yml

delegate_to: localhost

in a nut shell, you could dynamically modify an inventory and prep it for run, then spawn a shell to run ansible again. this way the 2nd spawn of ansible will pick up the modified inventory and do the work. may even be possible to do this with one playbook with some creative uses of extra-vars but easier just to make 2 playbooks..

Ovovitellin answered 26/8, 2022 at 21:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.