Amit Baid
Amit Baid

Reputation: 137

can I run a shell command in jinja2 template in ansible

This is a playbook that connects with all the servers in my inventory file, and makes a note of the server ip and mount point information of hosts where mount point usage exceeds 80% and it writes to a text file on the localhost (ansible-controller).

- hosts: all
  tasks:
    - shell:
         cmd: df -h | sed 's/%//g' | awk '$5 > 80 {if (NR > 1) print $5"%",$6}'
      register: disk_stat
    - debug:
         var: disk_stat

    - file:
         path: /home/app/space_report_{{ td }}.txt
         state: touch
      run_once: true
      delegate_to: localhost

    - shell: echo -e "{{ ansible_host }} '\n' {{ disk_stat.stdout_lines| to_nice_yaml }}" >> /home/thor/space_report_{{ td }}.txt
      args:
         executable: /bin/bash
      delegate_to: localhost

I was wondering if I could create a jinja2 template and bring the playbook down to one task. I am stuck at integrating a shell command inside the jinja2 template and I am not sure if it is possible. Please advise.

- hosts:  all
  tasks:
    - template:
        src: monitor.txt.j2
        dest: /home/app/playbooks/monitor.txt
      delegate_to: localhost

monitor.txt.j2

{% for host in groups['all'] %}
{{ hostvars[host].ansible_host }}
--shell command--
{% endfor %}

Upvotes: 3

Views: 14658

Answers (1)

Baptiste Mille-Mathias
Baptiste Mille-Mathias

Reputation: 2169

As I say in my comment under your question, while it is possible to use shell or command modules, Ansible is a configuration / automation tool, so it's better to forget your shell coding / logic to use native ansible functionalities, that'll ease the tasks / playbook writing.

For instance, it's no needed to do a df because ansible when connecting will gather facts about the target, including devices and their capacity and current usage so you can use that directly.

For the jinja question, you can use the module copy and pass directly jinja code in the option content on this module:

- name: Trigger a tasks on hosts to gather facts
  hosts: all
  tasks:
    
    - copy:
         dest: /home/app/playbooks/monitor.txt
         content: |
           {% for host in groups['all'] %}
           {% for dev in hostvars[host].ansible_mounts %}
           {% if (dev.block_used / dev.block_total * 100 ) > 80 %} {{ dev.block_used / dev.block_total * 100 }} {{ dev.mount }} {% endif %}
           {% endfor %}
           {% endfor %}
       run_once: true
       delegate_to: localhost

Upvotes: 1

Related Questions