Ansible: перебирать группы инвентаря - PullRequest
0 голосов
/ 08 декабря 2018

У меня есть группа tgt-cluster, в которую входят 3 хоста.Я записал роль для развертывания контейнера, который выполняется в группе tgt-cluster.Я контролирую количество контейнеров для развертывания с with_sequence.Мои задачи выглядят так:

- name: Deploy Container 
  docker_container:
    name: "C{{ item }}"
    image: "{{ image_name }}:{{ image_tag }}"
    recreate: yes
    detach: yes
    tty: yes
    interactive: yes
  with_sequence: count="{{ number_of_container_to_deploy }}"  

Если я хочу развернуть один контейнер, в настоящее время playbook выполняется на всех 3 хостах в группе tgt-cluster, и я получаю 3 контейнера.Итак, как я должен создать вложенный цикл в этом случае, чтобы контролировать выполнение задачи на хостах в режиме циклического перебора.

Скажем, если мы хотим развернуть 4 контейнера. 1-й контейнер должен быть развернут на 1-м хосте в группе, 2-й контейнер должен быть развернут на 2-м контейнере в группе, 3-й должен быть развернут на 3-х хостах в группе и 4-м контейнереследует развернуть обратно на 1-й хост в группе.

Я обновил файл переменной следующим образом, и переменной count_per_hosts присвоено значение with_sequence.Во время выполнения я получаю сообщение об ошибке "не могу разобрать arg count = u '' как целое число".Поэтому я обновил with_sequence: count="{{ count_per_hosts | int }}", и он не выдает ошибку, но не выполняет задачи, не пропуская ее.

the_hosts: "{{ groups['tgt-cluster']}}" 
num_hosts: "{{ the_hosts | length }}" 
count_per_hosts: > 
  "{% for x in range(number_of_container_to_deploy) %} 
    - set idx = x % num_hosts 
      set cc = assignment.get(the_hosts[idx], 0) 
      set _ = assignment.update({the_hosts[idx]: cc + 1}) 
  {% endfor %}"

В настоящее время мое исполнение выглядит следующим образом.deploy_container : Deploy Process Задачи должны создать контейнер, но мы не видим там никаких журналов.Кроме того, я попытался переместить the_hosts и num_hosts в count_per_hosts в том же синтаксисе, который указан в ответах, но выполнение не приводит к выводу.

PLAY [bin installation] **************************************************************************************************************************************************************************************
META: ran handlers

TASK [deploy_container : Deploy Process] *************************************************************************************************************************************************************
task path: /home/tg/Documents/playbooks/roles/deploy_container/tasks/main.yml:3
META: ran handlers
META: ran handlers

PLAY RECAP *****************************************************************************************************************************************************************************************************
br1.lab            : ok=0    changed=0    unreachable=0    failed=0
br2.lab            : ok=0    changed=0    unreachable=0    failed=0
br3.lab            : ok=0    changed=0    unreachable=0    failed=0

Кроме того, я попытался default(0), но ansible являетсяошибка{ "msg": "can't parse arg count=u\"#' # ' idx = x % num_hosts\\ncc = assignment.get(the_hosts[idx], 0)\\n_ = assignment.update({the_hosts[idx]: cc + 1})\\nidx = x % num_hosts\\ncc = assignment.get(the_hosts[idx], 0)\\n_ = assignment.update({the_hosts[idx]: cc + 1})\\n'\\n\" as integer" }

Текущая книга воспроизведения выглядит следующим образом:

- name: bin installation
  hosts: tgt-cluster
  user: "{{ user }}"
  gather_facts: no
  become: yes
  vars:
    count_per_hosts: |
      {% set the_hosts = groups["tgt-cluster"] %}
      {% set num_hosts = the_hosts | length %}
      {% set result = {} %}
      {% for x in range(number_of_process_to_deploy) %}
      {%   set idx = x % num_hosts %}
      {%   set h   = the_hosts[idx] %}
      {%   set cc  = result.get(h, 0) %}
      {%   set  _  = result.update({h: cc + 1}) %}
      {% endfor %}
      {{ result }}
  roles:
    - deploy_container

вывод с with_sequence: count="{{ count_per_hosts }}", если мы укажем with_sequence: count="{{ count_per_hostsget(ansible_hostname, 0) }}", мы получим fatal: [br1.lab]: FAILED! => {"msg": "'ansible_hostname' is undefined"}

TASK [deploy_container : Deploy Process] ***************************************************************************
fatal: [br1.lab]: FAILED! => {"msg": "can't parse arg count=u\"{u'br1.lab': 1, u'br2.lab': 1}\" as integer"}
fatal: [br2.lab]: FAILED! => {"msg": "can't parse arg count=u\"{u'br1.lab': 1, u'br2.lab': 1}\" as integer"}
fatal: [br3.lab]: FAILED! => {"msg": "can't parse arg count=u\"{u'br1.lab': 1, u'br2.lab': 1}\" as integer"}

Iпопытался зарегистрировать вывод и проверить, и запустил debug для просмотра содержимого и обнаружил, что он не может выбрать хост из группы.

ok: [br1.lab] => { "my_content": { "changed": false, "results": [], "skipped": true, "skipped_reason": "No items in the list" } }

1 Ответ

0 голосов
/ 08 декабря 2018

Вы будете намного счастливее, если будете выполнять подсчет самостоятельно:

vars:
  the_hosts: "{{ groups['tgt-cluster']}}" 
  num_hosts: "{{ the_hosts | length }}" 
  count_per_hosts: |
    {% set result = {} %}
    {% for x in range(number_of_container_to_deploy) %}
    {%   set idx = x % num_hosts %}
    {%   set h   = the_hosts[idx] %}
    {%   set cc  = result.get(h, 0) %}
    {%   set  _  = result.update({h: cc + 1}) %}
    {% endfor %}
    {{ result }}

Тогда в фактической задаче docker_container: вы теперь можете иметь with_sequence: счет на хост,и некоторые из них могут быть нулевыми:

- name: Deploy Container 
  docker_container:
    name: "C{{ item }}"
    image: "{{ image_name }}:{{ image_tag }}"
    recreate: yes
    detach: yes
    tty: yes
    interactive: yes
  with_sequence:
    count: "{{ count_per_hosts.get(ansible_hostname, 0) }}"
...