Как отслеживать, где вы находитесь в цикле Ansible?

Мне нужно написать несколько строк в файле YAML разное количество раз:

- name: Retry a task until a certain condition is met
  lineinfile:
    path: /root/file
    insertafter: '^listeners:'
    line: 'iteration #iteration_number++'
  retries: {{ a_variable }}
  delay: 10

Я также хочу записать в файл номер выполнения каждой итерации. Аналогично следующему циклу for:

for i in {1..a_variable}
  do
    echo "i"
  done

Как отслеживать, где вы находитесь в цикле?


66
2

Ответы:

Во-первых, повторы не являются циклами, поскольку они ничего не повторяют. Они просто опрашивают до тех пор, пока условие не будет выполнено. Вместо этого вам нужно поместить выполнение lineinfile в loop, которое будет выполнять итерацию в диапазоне от 0 до вашего значения. Что-то вроде этого (сейчас не могу подтвердить, просто показываю идею):

 - name: Retry a task until a certain condition is met
   lineinfile:
     path: /root/file
     insertafter: '^listeners:'
     line: 'iteration #iteration_number++'
   loop: "{{ lookup('range', 0, a_variable }}"

Затем вы можете использовать переменную item по умолчанию или установить для нее другую, используя необязательную директиву loop_var параметра loop_control.

Но это справедливо для простых случаев. В реальном мире приходится перебирать некоторый список объектов, поэтому Ansible предоставляет специальную переменную специально для этого случая. Это покрыто Отслеживание прогресса в цикле с помощью index_var:

Чтобы отслеживать, на каком этапе цикла вы находитесь, используйте директиву index_var с loop_control. Эта директива определяет имя переменной, которая будет содержать индекс текущего цикла.

    - name: Count our fruit
      ansible.builtin.debug:
        msg: "{{ item }} with index {{ my_idx }}"
      loop:
        - apple
        - banana
        - pear
      loop_control:
        index_var: my_idx

Вместо этого вы также можете рассмотреть возможность создания шаблона файла с помощью Jinja2.


Решено

Вопрос: «Аналогично следующему циклу for».

На основе уже заданной идеи , минимальный пример сценария.

---
- hosts: localhost
  become: false
  gather_facts: false

  tasks:

  - name: Echo index into file
    lineinfile:
      path: index.file
      create: true
      line: '{{ item }}'
    loop: "{{ range(1, i + 1, 1) }}"
    loop_control:
      extended: true
      label: "{{ ansible_loop.index }}"
    vars:
      i: 3

приведет к выводу

TASK [Echo index into file] ****
changed: [localhost] => (item=1)
changed: [localhost] => (item=2)
changed: [localhost] => (item=3)

и содержимое файла

cat index.file
1
2
3

Даже если это технически возможно, следует иметь в виду Дзен Ansible.

Если вы пытаетесь «писать код» в своих пьесах и ролях, вы обрекаете себя на неудачу. Учебники Ansible на основе YAML никогда не предназначались для программирования.

Документация


Интересные вопросы для изучения