Apakah ada cara untuk menjalankan loop with_items secara paralel di Ansible?

12

Saya menjalankan Ansible 2.2, tetapi dapat memutakhirkan jika itu membantu.

Saya melihat ini dan sangat bersemangat, tetapi sepertinya tidak ada dalam versi (atau apapun) dokumentasi Ansible ini.

Masalah yang saya coba selesaikan adalah saya punya 1000 pengguna yang perlu saya kelola pada kotak Centos.

Butuh waktu cukup lama untuk menjalankan tugas ini secara seri. Dan yang lebih menjengkelkan, semuanya muncul sebagai berubah karena perintah "kadaluwarsa" pada modul pengguna selalu menandai hal itu sebagai diubah.

ini juga tampak menjanjikan, tetapi butuh jumlah waktu yang sama untuk menjalankan setiap perintah dalam loop with_items dan tidak berjalan lebih cepat (saya tidak pernah repot-repot menunggu cukup lama untuk sampai ke akhir).

Melewati tugas cepat sekarang (jauh lebih cepat daripada di Ansible 2.0), jika saya tidak tahu cara membuat ini bekerja secara paralel, saya pikir saya akan kembali dan mencari cara untuk melewatkan tugas yang tidak berguna dan jika semua Jika tidak, saya akan menulis modul sendiri. Tapi sepertinya aku harus bisa melakukan ini lebih cepat di Ansible.


Ini yang ingin saya jalankan secara paralel, host_authorizationsadalah daftar nama pengguna dan data lainnya.

  - name: Create/modify OS user accounts
    user: name={{ item.username }} group=sshusers shell=/bin/bash home="/home/selinux-modules/{{ item.username }}" state=present expires={{item.expiredate|default(omit)}}
    with_items: "{{ host_authorizations }}"
    tags: full_maintenance
Peter Turner
sumber
Harap berikan cuplikan kode. Kalau tidak, sulit untuk membantu.
030
@ 030 ada cuplikan, saya kira itu membantu sedikit untuk konteks. Saya lebih tertarik secara konseptual jika memang ada cara untuk menjalankan tugas (dalam satu lingkaran) secara paralel pada host yang sama. Saya tahu saya bisa melakukan banyak hal individual dengan async, tetapi tidak begitu banyak dengan with_items.
Peter Turner
Jadi pada dasarnya jika 1000 pengguna harus dibuat maka itu harus diselesaikan secepat membuat hanya satu pengguna. Menarik, mengapa tidak menggunakan sesuatu seperti LDAP?
030
1
Serius, Anda sedang menuju jalan yang menyakitkan, saya tidak berpikir ada orang yang menangani lebih dari selusin akun dengan basis akun lokal, segera setelah jumlah pengguna bertambah, saya menganggap semua orang pindah ke sistem akuntansi terpusat, biasanya beberapa ldap backend (bisa berupa direktori aktif) dan kemudian mengatur waktu kadaluwarsa dan kunci publik sebagai atribut dari basis pusat ini kemudian menggunakan hal-hal seperti sss_ssh_authorizedkeys agar server ssh mendapatkan kunci resmi dari basis pusat ini.
Tensibai
2
Saya tidak setuju ini adalah apa yang dimungkinkan untuk (mengisyaratkan bahwa itu tidak melakukan pembuatan / manajemen pengguna massal). Saya berdiri pada titik bahwa akun tidak boleh dikelola berdasarkan basis akun lokal pada volume yang besar (fakta bahwa mereka bukan akun manusia tidak relevan dengan masalah ini)
Tensibai

Jawaban:

13

Seperti @webKnja menyebutkan ini dimungkinkan dengan asyncmode. Baru-baru ini saya menemukannya sendiri dan mengetahui bahwa Anda dapat menggunakannya dalam 3 cara berbeda tergantung pada kebutuhan Anda.

  1. Jalankan dan polling hasilnya, perhatikan poll:5, Ini akan polling hasilnya setiap 5 detik. Anda dapat menghemat waktu dengan metode ini.

    - name: My long runing task
      some_module_name:
        ip: "{{item.fabric}}"
        username: "{{user}}"
        password: "{{password}}"
        secret: "{{secret}}"
      loop: "{{zoning_list}}"
      register: _alias_vc_0
      async: 60
      poll: 5
    
  2. Api dan lupakan poll: 0 , ini adalah opsi yang sangat cepat karena Ansible itu hanya menembak keluar tugas-tugas itu. Sisi buruknya adalah bahwa kita tidak tahu apa hasil dari tugas yaitu changed: True/False. Tentu saja itu kerugian jika Anda peduli dengan umpan balik;).

    name: My long runing task
    some_module_name:
      ip: "{{item.fabric}}"
      username: "{{user}}"
      password: "{{password}}"
      secret: "{{secret}}"
    loop: "{{zoning_list}}"
    register: _alias_vc_0
    async: 60
    poll: 0
    
  3. Dipecat dan dilupakanasync_status , sintaks untuk tugasnya sama dengan contoh 2 yang membutuhkan tugas tambahan async_status. Ini adalah favorit saya karena ini relatif cepat (lebih cepat dari perulangan normal atau execute and poll) dan memungkinkan Anda untuk menangkap umpan balik meskipun akan perlu berurusan dengan yang baru registeruntuk Anda async_task.

    retries: 20 - berapa banyak upaya sebelum gagal.

    delay: 2 - berapa detik untuk menunggu di antara jajak pendapat.

    - name: My long runing task
      some_module_name:
        ip: "{{item.fabric}}"
        username: "{{user}}"
        password: "{{password}}"
        secret: "{{secret}}"
      loop: "{{zoning_list}}"
      register: _alias_vc_0
      async: 60
      poll: 0
    
    
    - name: Wait for My long running task to finish
      async_status:
        id: "{{ item.ansible_job_id }}"
      register: _jobs_alias_vc_0
      retries: 20
      delay: 2
      until: _jobs_alias_vc_0.finished
      loop: "{{_alias_vc_0.results}}"
    

Sebuah kata hati-hati , tergantung pada tugas kamu mungkin tidak dapat menggunakan asyncopsi. Saya punya contoh di mana saya berinteraksi dengan sistem yang tidak dapat menangani beberapa permintaan untuk sumber daya yang sama. Saya menemukan asyncopsi yang terbaik jika saya harus melakukan tugas yang sama di beberapa host. Di situlah saya bisa "menghemat" waktu paling banyak.

Karena Anda memposting tautan ke dokumentasi yang dimungkinkan dalam pertanyaan, saya tidak akan melakukannya.

MMT
sumber
@chicks Anda mungkin ingin mengubah pollnilai ke 0 pada contoh 3. Ini adalah penjelasan yang luar biasa !! Thnx.
Debanjan Basu
@DebanjanBasu Siapa saja dapat melakukan pengeditan yang disarankan. Saya mungkin orang yang menyetujuinya dalam antrian ulasan, tetapi Anda harus mendapatkan kredit untuk hasil edit itu sendiri.
anak ayam
Penyuntingan satu karakter tidak diizinkan dengan sedih! :(
Debanjan Basu
2
Opsi 3 berfungsi dengan baik, terima kasih! Namun satu komentar: setidaknya 2,8 Kemungkinan, async_statusmembutuhkan jid, tidak id.
EdwardTeach
4

Untuk menjawab pertanyaan Anda: Tidak, sampai sekarang Ansible tidak dapat menjalankan loop secara paralel.

Saya akan menggunakan newusers, yang dibuat untuk pembuatan pengguna massal Buat file dengan semua pengguna di dalamnya, salin ke host, dan jalankan newusers /path/to/user/listdalam commandtugas.

simonz
sumber
3

Dimungkinkan untuk mencapai asyncmode penggunaan ini . Silakan temukan beberapa referensi untuk melakukannya di bawah ini.

Referensi:

---

- name: Run tasks in parallel
  hosts: localhost
  connection: local
  gather_facts: no
  tasks:
    - name: Pretend to create instances
      command: "sleep {{ item }}"  # Instead of calling a long running operation at a cloud provider, we just sleep.
      with_items:
        - 6
        - 8
        - 7
      register: _create_instances
      async: 600  # Maximum runtime in seconds. Adjust as needed.
      poll: 0  # Fire and continue (never poll)

    - name: Wait for creation to finish
      async_status:
        jid: "{{ item.ansible_job_id }}"
      register: _jobs
      until: _jobs.finished
      delay: 5  # Check every 5 seconds. Adjust as you like.
      retries: 10  # Retry up to 10 times. Adjust as needed.
      with_items: "{{ _create_instances.results }}"
webKnjaZ
sumber
Meskipun tautan tersebut dapat menjawab pertanyaan jika rusak, tidak ada yang tersisa dalam jawaban Anda untuk pembaca di masa mendatang, harap coba tunjukkan bagaimana ini akan membantu menyelesaikan masalah dengan kata-kata Anda sendiri / contoh dan tinggalkan tautan untuk informasi lebih rinci saja.
Tensibai
ya, saya tidak dapat menandai ini sebagai jawaban sampai A.) Saya mengujinya dan B.) kode yang relevan ditempatkan di sini. Namun terima kasih telah menunjukkan saya ke arah ini.
Peter Turner
Maaf, saya terburu-buru :)
webKnjaZ