Ansible - extended shell execution format

I have 3 variables named IPOctet, ServerIPRange and epcrange. If I perform the following operation in the terminal, it works fine

IPOctet=$(echo "$ServerIPRange/$epcrange+$IPOctet" | bc) 

How can I do something like this inaccessible inside the task, for example,

 --- - hosts: localhost gather_facts: False vars_prompt: - name: epcrange prompt: Enter the number of EPCs that you want to configure private: False default: "1" - name: serverrange prompt: Enter the number of Clients that you want to configure private: False default: "1" - name: ServerIPRange prompt: Enter the ServerIP range private: False default: '128' - name: LastIPOctet prompt: Enter The last Octet of the IP you just entered private: False default: '10' pre_tasks: - name: Set some facts set_fact: ServerIP1: "{{ServerIP}}" ServerIPRange1: "{{ServerIPRange}}" IPOctet: "{{LastIPOctet}}" - name: local action math local_action: shell {{IPOctet}}=$(echo "${{ServerIPRange}}/${{epcrange}}+${{IPOctet}}" | bc) # Proper Syntax? with_sequence: start=1 end=4 register: result ignore_errors: yes 

What is the correct syntax for this command? Perhaps using shell echo ".......". I just need to save the contents of this command in the IPOctet variable, and the IPOctet will change with each iteration of the loop, and the results should be stored in my results registry

PS: how can I access the individual elements in the array separately?

Edit: something like this is possible, currently it just does the calculation once and saves it 4 times in the register ...

 - name: bashless math set_fact: IPOctet: "{{ (ServerIPRange|int/epcrange|int)+IPOctet|int }}" register: IPOctet with_sequence: "start=1 end={{stop}} " register: my_ip_octet 
+5
source share
2 answers
  • Your terminal expression reassigns the IPOctet shell variable, so each time it is executed, it gives a different result. This is fine, but hard to reproduce in Ansible:

     $ IPOctet=10 ServerIPRange=128 epcrange=1 $ IPOctet=$(echo "$ServerIPRange/$epcrange+$IPOctet" | bc); echo $IPOctet 138 $ IPOctet=$(echo "$ServerIPRange/$epcrange+$IPOctet" | bc); echo $IPOctet 266 
  • Syntax: "shell {{IPOctet}}=$(echo ..." DOES NOT assign an Ansible variable. The shell is trying to execute a command like "10=138" that was not found.

  • When a register is used in a loop, the target variable is not set until the loop completes - so your expression always sees the original value for {{IPOctet}} .

  • The solution is to run the entire cycle as one shell command:

     - name: local action math2 local_action: shell IPOctet={{IPOctet}}; for i in 1 2 3 4; do IPOctet=$(expr {{ServerIPRange}} / {{epcrange}} + $IPOctet); echo $IPOctet; done register: result 

    NOTE: I used the expr command, not bc , but the results are the same.

  • You can repeat these results using result.stdout_lines:

     - name: iterate results local_action: debug msg={{item}} with_items: result.stdout_lines 
+2
source

Firstly, your Jinja template is incorrect, each individual variable must be surrounded by two brackets. You cannot use multiple variables in the same pair of brackets. For instance,

 {{ ServerIPRange }} 

Secondly, set_fact is only used to set the fact value. You cannot run shell commands with set_fact. Instead, you should use a shell module.

 - name: local action math local_action: shell {{ IPOctet }}=$(echo {{ ServerIPRange|int }}/{{ epcrange|int }}+{{ IPOctet|int }}" | bc) with_sequence: start=1 end=4 register: result ignore_errors: yes 

Ansible will do the calculation 4 times and save it in the list as 4 different elements. You can verify that everything is stored inside this list, and even access it by going through it.

 - debug: msg={{ result }} 

Hope this helps :)

+2
source

Source: https://habr.com/ru/post/1200882/


All Articles