Apa perbedaan antara include_tasks dan import_tasks?

63

Dalam Ansible 2.4, includemodul tidak digunakan lagi. Sebagai gantinya, ia dikirimkan dengan dua modul pengganti, import_tasksdan include_tasks. Tetapi mereka memiliki deskripsi yang sangat mirip:

  • include_tasks: Termasuk file dengan daftar tugas yang akan dieksekusi di buku pedoman saat ini.
  • import_tasks: Mengimpor daftar tugas yang akan ditambahkan ke playbook saat ini untuk eksekusi selanjutnya.

Kapan saya harus menggunakan yang pertama, dan kapan saya harus menggunakan yang kedua?

Ben S
sumber
(Juga: peringatan penghentian mengacu pada tugas "dinamis" dan "statis". Saya membaca dokumen tetapi tidak memahaminya.)
Ben S

Jawaban:

70

Ada cukup banyak tentang topik ini dalam dokumentasi:

Perbedaan utama adalah:

Semua import*pernyataan sudah diproses pada saat playbook diuraikan.
Semua include*pernyataan diproses saat mereka temui selama pelaksanaan playbook.

Begitu importjuga statis, includedinamis.

Dari pengalaman saya, Anda harus menggunakan importketika Anda berurusan dengan "unit" logis. Misalnya, pisahkan daftar tugas yang panjang ke dalam file subtugas:

main.yml:

- import_tasks: prepare_filesystem.yml
- import_tasks: install_prerequisites.yml
- import_tasks: install_application.yml

Tetapi Anda akan terbiasa includemenghadapi alur kerja yang berbeda dan mengambil keputusan berdasarkan beberapa fakta yang dikumpulkan secara dinamis:

install_prasyarat:

- include_tasks: prerequisites_{{ ansible_os_family | lower }}.yml
Konstantin Suvorov
sumber
8
Saya menemukan tautan ini sangat berguna: docs.ansible.com/ansible/latest/... Ia menyebutkan kasus di mana impor dan termasuk berperilaku berbeda - kondisi 'ketika' di mana tugas-tugas dalam file dapat mengubah kriteria yang digunakan untuk menentukan impor. . Dengan import_tasks, setiap tugas memeriksa kriteria, sehingga perilaku berubah ketika kriteria berubah. Dengan include_tasks, tugas ada atau tidak berdasarkan pada apakah atau tidak kondisi dievaluasi sebagai benar ketika pernyataan include_tasks dieksekusi. Jika saya mengerti dengan baik ...
Ethel Evans
Apa kelakuannya include? Jika kita menggunakan includeakan import_taskssetara?
Andy Shinn
includetelah static: yes(berperilaku seperti import_tasks), dan static: no(suka include_tasks).
Konstantin Suvorov
Untuk apa standarnya static?
Andy Shinn
staticsecara Nonedefault: Karena Ansible 2.0, tugas termasuk bersifat dinamis dan berperilaku lebih seperti tugas nyata. Ini berarti mereka dapat diulang, dilewati dan menggunakan variabel dari sumber apa pun. Ansible mencoba mendeteksi ini secara otomatis, tetapi Anda dapat menggunakan arahan statis (yang ditambahkan pada An 2.1) untuk memintas deteksi otomatis.
Konstantin Suvorov
17

Impor statis, termasuk dinamis. Impor terjadi pada waktu parsing, termasuk saat runtime.

Impor pada dasarnya mengganti tugas dengan tugas dari file. Tidak ada import_tasksaat runtime. Jadi, atribut like tags, dan when(dan kemungkinan besar atribut lainnya) disalin ke setiap tugas yang diimpor.

includeMemang dieksekusi. tagsdan whentugas yang disertakan hanya berlaku untuk tugas itu sendiri.

importTugas yang ditandai dari file yang diimpor dijalankan jika tugas tidak diberi tag. Tidak ada tugas yang dieksekusi dari file yang disertakan jika includetugas tersebut tidak ditandai.

Semua tugas dari file yang diimpor dieksekusi jika importtugas ditandai. Hanya tugas yang ditandai dari file yang disertakan yang dieksekusi jika includetugas ditandai.

Keterbatasan imports:

  • tidak dapat digunakan dengan with_*atau loopatribut
  • tidak dapat mengimpor file, yang namanya tergantung pada variabel

Keterbatasan includes:

  • --list-tags tidak menampilkan tag dari file yang disertakan
  • --list-tasks tidak menampilkan tugas dari file yang disertakan
  • Anda tidak dapat menggunakan notifyuntuk memicu nama penangan yang berasal dari dalam dinamis termasuk
  • Anda tidak dapat menggunakan --start-at-taskuntuk memulai eksekusi pada tugas di dalam dinamis termasuk

Lebih lanjut tentang ini di sini dan di sini .

Bagi saya itu pada dasarnya datang ke fakta bahwa imports tidak dapat digunakan dengan atribut loop.

importpasti akan gagal dalam kasus-kasus seperti ini :

# playbook.yml
- import_tasks: set-x.yml
  when: x is not defined

# set-x.yml
- set_fact
  x: foo
- debug:
  var: x

debugtidak dieksekusi, karena ia mewarisi whendari import_taskstugas. Jadi, tidak ada mengimpor file tugas yang mengubah variabel yang digunakan dalam import's whenatribut.

Saya memiliki kebijakan untuk memulai dengan imports, tetapi begitu saya perlu includememastikan tidak ada yang diimpor oleh file yang disertakan atau file yang disertakan. Tapi itu sangat sulit dipertahankan. Dan masih belum jelas apakah itu akan melindungi saya dari masalah. Artinya, mencampur includes dan imports yang tidak mereka rekomendasikan.

Saya tidak bisa menggunakan imports saja , karena saya kadang-kadang perlu mengulang includetugas. Saya mungkin bisa beralih ke hanya includes. Tetapi saya memutuskan untuk beralih ke impor di mana-mana kecuali untuk kasus-kasus di mana tugas seharusnya dijalankan beberapa kali. Saya memutuskan untuk mengalami sendiri semua kasus tepi yang rumit itu secara langsung. Mungkin tidak akan ada di buku pedoman saya. Atau mudah-mudahan saya akan menemukan cara untuk membuatnya bekerja.

UPD Trik yang mungkin berguna untuk membuat file tugas yang dapat diimpor berkali-kali, tetapi dieksekusi sekali :

- name: ...
  ...
  when: not _file_executed | default(False)

- name: ...
  ...
  when: not _file_executed | default(False)

...

- name: Set _file_executed
  set_fact:
    _file_executed: True

UPD. Satu efek yang tidak benar-benar diharapkan dari pencampuran termasuk dan impor adalah bahwa termasuk vars menimpa yang impor:

playbook.yml:

- hosts: all
  tasks:
    - import_tasks: 2.yml
      vars:
        v1: 1
    - include_tasks: 2.yml
      vars:
        v1: 1

2.yml:

- import_tasks: 3.yml
  vars:
    v1: 2

3.yml:

- debug:
    var: v1    # 2 then 1

Mungkin, karena include_taskspertama-tama melakukan semua impor statis tambahan, dan kemudian perubahan variabel melewati varsarahannya.

Sebenarnya, itu tidak hanya terjadi pada impor:

playbook.yml:

- hosts: all
  tasks:
    - import_tasks: 2.yml
      vars:
        v1: 1
    - include_tasks: 2.yml
      vars:
        v1: 1

2.yml:

- debug:
    var: v1    # 2 then 1
  vars:
    v1: 2

UPD Kasus pencampuran lainnya termasuk dan impor.

playbook.yml:

- hosts: all
  tasks:
    # here you're bound to use include, some sort of loop
    - include_tasks: 2.yml
      vars:
        https: yes

2.yml:

- import_tasks: 3.yml
  when: https

3.yml:

- import_tasks: 4.yml
  vars:
    https: no  # here we're trying to temporarily override https var
- import_tasks: 4.yml

4.yml:

- debug:
    var: https

Kami mendapatkan truedan true, melihat kasus sebelumnya (termasuk vars diutamakan daripada vars impor). Jadi kami beralih ke memasukkan dalam 3.yml. Tapi kemudian yang pertama termasuk 3.ymldilewati. Karena itu mewarisi when: httpsdari tugas induk, dan yang terakhir diduga mengambil httpsdari tugas itu vars. Solusinya adalah beralih ke memasukkan 2.ymljuga. Itu mencegah penyebaran when: httpske tugas anak.

x-yuri
sumber
4
Jawaban yang bagus! Saya merasa frustrasi dengan semua orang di internet hanya mengulangi apa yang dikatakan dokumentasi. Terima kasih.
Sergio Acosta