Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

in ansible can I use a variable for a module instead of using the module name?

Tags:

ansible

I'm using ansible 2.9 and I would like to know if I can use a variable instead of the actual module name. For example:

---
- name: A Network play
  hosts: routers
  vars:
    router_module: ios_command
  tasks:
    - name: a network task
      {{router_module}}:
        commands:
          - show ip int brief 
like image 937
John Avatar asked Sep 15 '25 20:09

John


1 Answers

No. You can't use a variable for the module, but you can dynamically create files with tasks from a template and include the files in a playbook. For example, see the playbook and the template below

shell> cat test.yml
- hosts: localhost

  vars:

    pb_tasks:
      - module: debug
        params:
          - {key: var, val: inventory_hostname}
      - module: debug
        params:
          - {key: msg, val: End of dynamic play}

  tasks:

    - file:
        state: directory
        path: tasks

    - template:
        src: task.yml.j2
        dest: tasks/task-{{ ansible_loop.index }}.yml
      loop: "{{ pb_tasks }}"
      loop_control:
        extended: true

    - include_tasks: tasks/task-{{ ansible_loop.index }}.yml
      loop: "{{ pb_tasks }}"
      loop_control:
        extended: true
shell> cat task.yml.j2
- {{ item.module }}:
{% for param in item.params %}
    {{ param.key }}: {{ param.val }}
{% endfor %}

In the loop, the task "template" creates the files with the tasks

shell> tree tasks
tasks
├── task-1.yml
└── task-2.yml

0 directories, 2 files
shell> cat tasks/task-1.yml 
- debug:
    var: inventory_hostname
shell> cat tasks/task-2.yml 
- debug:
    msg: End of dynamic play

The next task in the playbook includes these files in the loop. The playbook gives

shell> ansible-playbook test.yml 

PLAY [localhost] ****

TASK [file] ****
ok: [localhost]

TASK [template] ****
changed: [localhost] => (item={'module': 'debug', 'params': [{'key': 'var', 'val': 'inventory_hostname'}]})
changed: [localhost] => (item={'module': 'debug', 'params': [{'key': 'msg', 'val': 'End of dynamic play'}]})

TASK [include_tasks] ****
included: /scratch/tasks/task-1.yml for localhost
included: /scratch/tasks/task-2.yml for localhost

TASK [debug] ****
ok: [localhost] => {
    "inventory_hostname": "localhost"
}

TASK [debug] ****
ok: [localhost] => {
    "msg": "End of dynamic play"
}

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

The same can be simplified with a dynamically created playbook. For example, see the playbook and the template below

shell> cat test.yml
- name: Create playbook from template
  hosts: localhost
  gather_facts: false

  vars:

    pb_tasks:
      - module: debug
        params:
          - {key: var, val: inventory_hostname}
      - module: debug
        params:
          - {key: msg, val: End of play}

  tasks:

    - template:
        src: playbook.yml.j2
        dest: playbook.yml
shell> cat playbook.yml.j2
- hosts: localhost
  gather_facts: false
  tasks:
{% for item in pb_tasks %}
    - {{ item.module }}:
{% for param in item.params %}
        {{ param.key }}: {{ param.val }}
{% endfor %}
{% endfor %}

The task "template" creates the playbook

shell> cat playbook.yml
- hosts: localhost
  gather_facts: false

  tasks:

    - debug:
        var: inventory_hostname

    - debug:
        msg: End of play

Then the playbook gives

shell> ansible-playbook playbook.yml

PLAY [localhost] ****

TASK [debug] ****
ok: [localhost] => {
    "inventory_hostname": "localhost"
}

TASK [debug] ****
ok: [localhost] => {
    "msg": "End of play"
}

PLAY RECAP ****
localhost: ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
like image 136
Vladimir Botka Avatar answered Sep 19 '25 10:09

Vladimir Botka



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!