user2814520
user2814520

Reputation: 73

Run tasks on hosts defined in yaml file instead of inventory using ansible

I'm new to Ansible and trying to fetch hosts from below config.yaml file instead of inventory, to run tasks on those hosts. How can I do this in main playbook?

service:
  web-app:
    common:
     tomcat:
      port: 80
  hosts:
      all:
         - abc.com
         - pqr.com

Is there a way to access abc.com and pqr.com in my playbook, if I have to run certain tasks on those servers?

Upvotes: 1

Views: 1228

Answers (1)

Zeitounator
Zeitounator

Reputation: 44615

The base: loading the data

The base ansible functions needed for the following examples are:

  1. The file lookup plugin to load the content of a file present on the controller.
  2. The from_yaml filter to read the file content as yaml formatted data

For both examples below, I added your above yaml example (after fixing the indentation issues) to files/service_config.yml. Simply change the name of the file if it is in a files subdir, or use the full path to the file if it is outside of your project.

Combining the above, you can get your list of hosts with the following jinja2 expression.

{{ (lookup('file', 'service_config.yml') | from_yaml).service.hosts.all }}

Note: if your custom yaml file is not present on your controller, you will firts need to get the data locally by using the slurp or fetch modules

Use in memory inventory

In this example, I create a dynamic group custom_group running a add_hosttask on a play targeted to localhost and later target that custom group in the next play. This is probably the best option if you have a large set of tasks to run on those hosts.

---
- name: Prepare environment
  hosts: localhost
  gather_facts: false

  vars:
    # Replace with full path to actual file
    # if this one is not in your 'files' subdir
    my_config_file: service_config.yml
    my_custom_hosts: "{{ (lookup('file', my_config_file) | from_yaml).service.hosts.all }}"

  tasks:
    - name: Create dynamic group from custom yaml file
      add_host:
        name: "{{ item }}"
        group: custom_group
      loop: "{{ my_custom_hosts }}"

- name: Play on new custom group
  hosts: custom_group
  gather_facts: false

  tasks:
    - name: Show we can actually contact the group
      debug:
        var: inventory_hostname

Which gives:

PLAY [Prepare environment] **********************************************************************************************************************************************************************************************************************************************

TASK [Create dynamic group from custom yaml file] ***********************************************************************************************************************************************************************************************************************
changed: [localhost] => (item=abc.com)
changed: [localhost] => (item=pqr.com)

PLAY [Play on new custom group] *****************************************************************************************************************************************************************************************************************************************

TASK [Show we can actually contact the group] ***************************************************************************************************************************************************************************************************************************
ok: [abc.com] => {
    "inventory_hostname": "abc.com"
}
ok: [pqr.com] => {
    "inventory_hostname": "pqr.com"
}

PLAY RECAP **************************************************************************************************************************************************************************************************************************************************************
abc.com                    : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
localhost                  : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
pqr.com                    : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0  

Use delegation

In the following example, I use task delegation to change the target host inside a play targeted to other hosts.

This is more suited if you have few tasks to run on the custom hosts and/or you need facts from the current play hosts to run those tasks. See the load balancer example in the above doc for a more in depth explanation.

---
- name: Delegation example
  hosts: localhost
  gather_facts: false

  vars:
    # Replace with full path to actual file
    # if this one is not in your 'files' subdir
    my_config_file: service_config.yml
    my_custom_hosts: "{{ (lookup('file', my_config_file) | from_yaml).service.hosts.all }}"

  tasks:
    - name: Task played on our current target host list
      debug:
        var: inventory_hostname

    - name: Fake task delegated to our list of custom host
      # Note: we play it only once so it does not repeat
      # if the play `hosts` param is a group of several targets
      # This is for example only and is not really delegating
      # anything in this case. Replace with your real life task
      debug:
        msg: "I would run on {{ item }} with facts from {{ inventory_hostname }}"
      delegate_to: "{{ item }}"
      run_once: true
      loop: "{{ my_custom_hosts }}"

Which gives:

PLAY [Delegation example] ***********************************************************************************************************************************************************************************************************************************************

TASK [Task played on our current target host list] **********************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "inventory_hostname": "localhost"
}

TASK [Fake task delegated to our list of custom host] *******************************************************************************************************************************************************************************************************************
ok: [localhost -> abc.com] => (item=abc.com) => {
    "msg": "I would run on abc.com with facts from localhost"
}
ok: [localhost -> pqr.com] => (item=pqr.com) => {
    "msg": "I would run on pqr.com with facts from localhost"
}

PLAY RECAP **************************************************************************************************************************************************************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Upvotes: 2

Related Questions