Выполнить задачу хоста в роли и делегировать другую задачу другому хосту в другой роли

Выполнить задачу хоста в роли и делегировать другую задачу другому хосту в другой роли


Контекст:

У меня есть проект с двумя ролями.
Я сократил количество задач до проблемных для лучшего понимания.


Проблема:
Я запускаю задачу из роли 1 на сервере 1 и пытаюсь делегировать задачу виртуализатору vmware из условия в первой задаче роли сервера 1. И хост выходит из строя, потому что он хочет выполнить вторую задачу роли (Vmware) на сервере 1.


Ошибка:

fatal: [testhost]: FAILED! => {"reason": "conflicting action statements: hosts, 
gather_facts\n\nThe error appears to be in '/home/ancible/proyects/extend_fs-role/roles/vmwaretaks/tasks/addvmwaredisk.yml': line 2, column 3, 
but may\nbe elsewhere in the file depending on tntax problem.\n\nThe offending line appears to be:\n\n---\n- hosts: localhost\n  ^ here\n"}


Вот структура:

.
├── collections
│   └── requirements.yml
├── README.md
├── resizefs_hosts.yml
└── roles
    ├── resizefs
    │   ├── defaults
    │   │   └── main.yml
    │   ├── handlers
    │   │   └── main.yml
    │   ├── meta
    │   │   └── main.yml
    │   ├── tasks
    │   │   ├── main.yml
    │   │   ├── findfreedisk.yml
    │   ├── tests
    │   │   ├── inventory
    │   │   └── test.yml
    │   └── vars
    │       └── main.yml
    └── vmwaretaks
        ├── defaults
        │   └── main.yml
        ├── files
        ├── handlers
        │   └── main.yml
        ├── meta
        │   └── main.yml
        ├── README.md
        ├── tasks
        │   ├── main.yml
        │   ├── addvmwaredisk.yml
        ├── templates
        ├── tests
        │   ├── inventory
        │   └── test.yml
        └── vars
            └── main.yml


Это порядок выполнения в случае, если на хосте не найден свободный логический узел:

resizefs_role_hosts.yml -> roles/resizefs/tasks/main.yml -> roles/resizefs/tasks/findfreedisk.yml -> \
roles/vmwaretaks/tasks/main.yml -> roles/vmwaretaks/tasks/addvmwaredisk.yml


Вот как выглядят эти сценарии:

$ cat  resizefs_role_hosts.yml
---
- hosts: testhost
  become: yes
  become_method: sudo
  roles:
    - role: 'roles/resizefs'
$ cat roles/resizefs/tasks/main.yml
---
# tasks file for create_fs-test
- import_tasks: findfreedisk.yml
$ cat roles/resizefs/tasks/findfreedisk.yml

- name: Finding disk with no partitions
  set_fact:
    disks: "/dev/{{outer_item.key}}"
  when:
    - not outer_item.value.partitions
    - not outer_item.value.links.ids
    - outer_item.key is search ("sd")
  with_dict: '{{ansible_devices}}'
  loop_control:
    loop_var: outer_item
  notify:
    - Format_free_disk
  changed_when: true

- name: Print disk name if available
  debug:
    msg:
      - "{{ disks|default('NOT FREE DISK') }} Available"

# If not disk available add new lun from Vmware
- include_role:
    name: vmwaretaks
  when: disks is undefined
$ cat roles/vmwaretaks/tasks/main.yml
---
# tasks file for add-new-vmware-lun
- import_tasks: addvmwaredisk.yml
$ cat roles/vmwaretaks/tasks/addvmwaredisk.yml

---
- hosts: localhost
  gather_facts: true

  vars:
    vcenter_hostname: 'vcenter.labo.local'
    vcenter_username: 'labo.local\ansible'
    vcenter_password: "{{ vault_pass }}"
    target_host: 'TESTHOST'
    vm_uuid: '4217B33E-014D-E056-0719-45AD3AC1861E'
    vm_unit_number: '5'

  tasks:
    - name: Add disks to virtual machine using UUID
      vmware_guest_disk:
        hostname: "{{ vcenter_hostname }}"
        username: "{{ vcenter_username }}"
        password: "{{ vcenter_password }}"
        datacenter: "{{ vcenter_hostname }}"
        uuid: "{{ vm_uuid | lower }}"
        validate_certs: no
        disk:
          - size_gb: 10
            type: 'thick'
            state: 'present'
            autoselect_datastore: yes
            scsi_controller: '0'
            scsi_type: 'paravirtual'
            unit_number: '5'
            disk_mode: 'independent_persistent'
      delegate_to: localhost

Я пытался найти способ сообщить ему, что вторая роль выполняется не на сервере, а в виртуализаторе vmware, но безуспешно.
Если я запускаю addvmwaredisk.yml как плейбук, он работает идеально.

Надеюсь, вы сможете помочь!

Спасибо заранее!

решение1

hostsи tasksявляются ключевыми словами play, их нельзя использовать внутри списка задач. Чтобы выполнить задачи на другом хосте, чем текущий хост play, используйтеделегация; чтобы сгруппировать связанные задачи и применить директивы ко всем из них, используйтеблокировать.

- delegate_to: localhost
  vars:
    vcenter_hostname: 'vcenter.labo.local'
    vcenter_username: 'labo.local\ansible'
    vcenter_password: "{{ vault_pass }}"
    target_host: 'TESTHOST'
    vm_uuid: '4217B33E-014D-E056-0719-45AD3AC1861E'
    vm_unit_number: '5'
  block:
    - name: Add disks to virtual machine using UUID
      vmware_guest_disk:
        hostname: "{{ vcenter_hostname }}"
        username: "{{ vcenter_username }}"
        password: "{{ vcenter_password }}"
        datacenter: "{{ vcenter_hostname }}"
        uuid: "{{ vm_uuid | lower }}"
        validate_certs: no
        disk:
          - size_gb: 10
            type: 'thick'
            state: 'present'
            autoselect_datastore: yes
            scsi_controller: '0'
            scsi_type: 'paravirtual'
            unit_number: '5'
            disk_mode: 'independent_persistent'

решение2

ну, я недавно решил эту проблему, просто добавивстать: нет

- delegate_to: localhost
  become: no
  delegate_facts: yes

Связанный контент