Home > Enterprise >  How can I call python directly inside Ansible playbook, in a for loop?
How can I call python directly inside Ansible playbook, in a for loop?

Time:01-27

I have developed a playbooks that sends a mail indicating a list of 3-zero-padded numbers.

I want to make the padding in the for loop which prints the information in the mail body.

The playbook takes the number to pad from variable hostvars[host]['number'].

The padding is made via the Ansible syntax

myhost-{{ 'd' % hostvars[host]['number']|int }}

as you can see in the following task.

Now, I would like to do the padding via Python, because later I want to make more formatting operations on each element printed by the loop.

So I have tried to substitute the upper line with

{{ "myhost-"   str(hostvars[host]['number']).zfill(3) }}

but I am getting this error:

Sending e-mail report...

  localhost failed | msg: The task includes an option with an undefined variable. The error was: 'str' is undefined

So I tryed to substitute it (as suggested in comments of this question) with

myhost-{{ hostvars[host].number.zfill(3) }}

but now I get

Sending e-mail report...

  localhost failed: {

    "msg": "The task includes an option with an undefined variable. The error was: 'int object' has no attribute 'zfill'    
}

So, how can I call python inside the for loop in order to manipulate the information to print with Python instead than Ansible?

Note: I want to call python directly in the loop and I don't want to define variable in python and substitute them into the body of the mail.

the task of my playbook:

    - name: Sending e-mail report
          community.general.mail:
            host: myhost
            port: 25
            sender: mymail
            to:
              - [email protected]

            subject: "mail of day {{ current_date }}"
            subtype: html

            body: |

              <br>title
              <br>text
              
              {% for host in mylist %}
              myhost-{{ 'd' % hostvars[host]['number']|int }}
              <br>
              {% endfor %}

              <br>text
              <br>closure

CodePudding user response:

SOLVED

Since the first time the error was raised by the use of bulit-in python str() function , while other elements of python syntax did not raise any error, I guessed python built-in functions cannot be interpreted by Ansible (still I don't understand why).

So I looked up for a way to do the data manipulation by using some python methods of the object, instead than a python function.

So instead of turning the int object into a string with str(my_object), I exploited the int python method .__str__().

So I substituted the upper line with

myhost-{{ hostvars[host].number.__str__().zfill(3) }}

and this time it worked.

Conclusion

This makes me think one cannot use python functions inside ansible {{ }} tags, but only python objects methods.

  • Related