Ansible - Advanced shell command execution format Ansible - Advanced shell command execution format shell shell

Ansible - Advanced shell command execution format


  1. Your terminal expression reassigns the IPOctet shell variable, so it gives a different result each time it is executed. This is fine, but difficult to reproduce in Ansible:

    $ IPOctet=10 ServerIPRange=128 epcrange=1$ IPOctet=$(echo "$ServerIPRange/$epcrange+$IPOctet" | bc); echo $IPOctet138$ IPOctet=$(echo "$ServerIPRange/$epcrange+$IPOctet" | bc); echo $IPOctet266
  2. The syntax: "shell {{IPOctet}}=$(echo ..." does NOT assign to the Ansible variable.The shell attempts to execute a command like "10=138", which is not found.

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

  4. A solution is to run the whole loop as a single 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've used the expr command rather than bc, but the results are the same.

  5. You can iterate over these results using result.stdout_lines:

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


Firstly your Jinja template is incorrect, every single variable needs to be surrounded with a pair of brackets. You can not use multiple variables within single pair of brackets. For example,

{{ ServerIPRange }}

Secondly, set_fact is used only to set a fact value. You can not run shell commands using set_fact. You should use shell module instead.

- 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 store it in a list as 4 different elements. You can check what all is stored inside this list and can even access it by looping over it.

- debug: msg={{ result }}

Hope this helps :)