ความแตกต่างระหว่าง include_tasks และ import_tasks คืออะไร


62

ใน Ansible 2.4 includeโมดูลเลิกใช้แล้ว ในสถานที่ของมันก็มาพร้อมกับสองโมดูลทดแทนและimport_tasks include_tasksแต่พวกเขามีคำอธิบายที่คล้ายกันมาก:

  • include_tasks: รวมไฟล์ที่มีรายการงานที่ต้องดำเนินการใน playbook ปัจจุบัน
  • import_tasks: นำเข้ารายการงานที่จะเพิ่มลงใน playbook ปัจจุบันสำหรับการดำเนินการที่ตามมา

ฉันควรใช้แบบเก่าเมื่อใดและควรใช้ครั้งหลังเมื่อใด


(นอกจากนี้: คำเตือนเลิกหมายถึง "พลัง" และงาน "คงที่" ผมอ่านเอกสาร แต่ไม่เข้าใจพวกเขา..)
เบน S

คำตอบ:


68

มีค่อนข้างน้อยเกี่ยวกับหัวข้อนี้ในเอกสารประกอบ:

ความแตกต่างที่สำคัญคือ:

import*งบทั้งหมดจะถูกประมวลผลล่วงหน้าในเวลา playbooks จะแยกวิเคราะห์ งบ
ทั้งหมดinclude*จะถูกประมวลผลตามที่พวกเขาพบในระหว่างการดำเนินการของ playbook

ดังนั้นimportเป็นแบบคงที่includeเป็นแบบไดนามิก

จากประสบการณ์ของฉันคุณควรใช้importเมื่อคุณจัดการกับ "หน่วย" ตรรกะ ตัวอย่างเช่นแยกรายการงานยาวออกเป็นไฟล์ย่อย:

main.yml:

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

แต่คุณจะใช้includeเพื่อจัดการกับเวิร์กโฟลว์ที่แตกต่างกันและตัดสินใจตามข้อเท็จจริงที่รวบรวมได้แบบไดนามิก:

install_prerequisites:

- include_tasks: prerequisites_{{ ansible_os_family | lower }}.yml

8
ฉันพบว่าลิงก์นี้มีประโยชน์มาก: docs.ansible.com/ansible/latest/…มันเรียกกรณีที่นำเข้าและรวมถึงพฤติกรรมที่แตกต่าง - 'เมื่อ' ตามเงื่อนไขที่งานในไฟล์อาจเปลี่ยนเกณฑ์ที่ใช้ในการกำหนดการนำเข้า . ด้วย import_tasks แต่ละงานจะตรวจสอบเกณฑ์ดังนั้นพฤติกรรมจะเปลี่ยนไปเมื่อมีการเปลี่ยนแปลงเกณฑ์ ด้วย include_tasks งานจะมีอยู่หรือไม่ขึ้นอยู่กับว่าเงื่อนไขถูกประเมินว่าเป็นจริงเมื่อคำสั่ง include_tasks ถูกเรียกใช้หรือไม่ ถ้าฉันเข้าใจดี ...
Ethel Evans

พฤติกรรมของincludeอะไร ถ้าเราใช้includeจะimport_tasksเท่ากับหรือไม่
Andy Shinn

includeมีstatic: yes(ประพฤติเหมือนimport_tasks) และstatic: no(ชอบinclude_tasks)
Konstantin Suvorov

ค่าเริ่มต้นstaticคืออะไร
Andy Shinn

staticเป็นNoneค่าเริ่มต้น: เนื่องจาก Ansible 2.0 การรวมงานจึงเป็นแบบไดนามิกและทำงานเหมือนงานจริงมากขึ้น ซึ่งหมายความว่าสามารถวนลูปข้ามและใช้ตัวแปรจากแหล่งใดก็ได้ Ansible พยายามตรวจจับสิ่งนี้โดยอัตโนมัติ แต่คุณสามารถใช้คำสั่งคงที่ (ซึ่งถูกเพิ่มใน Ansible 2.1) เพื่อข้ามการตรวจจับอัตโนมัติ
Konstantin Suvorov

15

การนำเข้าเป็นแบบคงที่รวมถึงเป็นแบบไดนามิก การนำเข้าเกิดขึ้นในเวลาการแยกวิเคราะห์รวมถึงตอนรันไทม์

โดยทั่วไปการนำเข้าจะแทนที่งานด้วยงานจากไฟล์ ไม่มีimport_taskเวลาทำงาน ดังนั้นคุณลักษณะเช่นtagsและwhen(และคุณลักษณะอื่น ๆ ที่น่าจะเป็นไปได้มากที่สุด) จะถูกคัดลอกไปยังงานนำเข้าทุกงาน

includes ถูกประหารชีวิตแน่นอน tagsและwhenรวมถึงงานที่ใช้กับงานตัวเองเท่านั้น

งานที่ติดแท็กจากไฟล์ที่นำเข้าจะถูกเรียกใช้importงานถ้าไม่ได้ติดแท็ก ไม่มีการดำเนินการงานจากไฟล์ที่รวมอยู่หากincludeไม่ได้ติดแท็กงาน

งานทั้งหมดจากไฟล์ที่นำเข้าจะถูกดำเนินการหากimportมีการแท็ก งานที่ติดแท็กจากไฟล์ที่รวมมาเท่านั้นที่จะถูกดำเนินการหากincludeงานถูกแท็ก

ข้อ จำกัด ของimports:

  • ไม่สามารถใช้กับwith_*หรือloopแอตทริบิวต์
  • ไม่สามารถนำเข้าไฟล์ซึ่งชื่อขึ้นอยู่กับตัวแปร

ข้อ จำกัด ของincludes:

  • --list-tags ไม่แสดงแท็กจากไฟล์ที่รวมอยู่
  • --list-tasks ไม่แสดงงานจากไฟล์ที่รวมอยู่
  • คุณไม่สามารถใช้notifyเพื่อเรียกชื่อตัวจัดการที่มาจากภายในแบบไดนามิกรวม
  • คุณไม่สามารถใช้--start-at-taskเพื่อเริ่มการทำงานที่งานภายในการรวมแบบไดนามิก

เพิ่มเติมเกี่ยวกับมันที่นี่และที่นี่

สำหรับฉันแล้วโดยพื้นฐานนั้นมาจากความจริงที่ว่าimportไม่สามารถใช้กับแอตทริบิวต์ลูปได้

importจะล้มเหลวอย่างแน่นอนในกรณีเช่นนี้ :

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

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

debugไม่ได้ถูกดำเนินการเนื่องจากสืบทอดwhenมาจากimport_tasksภารกิจ ดังนั้นไม่ใช่เรื่องการนำเข้าไฟล์ว่าตัวแปรที่ใช้ในการเปลี่ยนแปลงimportของwhenแอตทริบิวต์

ฉันมีนโยบายที่จะเริ่มต้นด้วยimports แต่เมื่อฉันต้องการincludeให้แน่ใจว่าไม่มีสิ่งใดถูกนำเข้าโดยไฟล์ที่รวมอยู่หรือไฟล์ที่มีอยู่ แต่มันก็ยากที่จะดูแล และยังไม่ชัดเจนว่าจะป้องกันฉันจากปัญหา ความหมายการผสมincludeและการimportที่พวกเขาไม่แนะนำ

ฉันไม่สามารถใช้เฉพาะimports เนื่องจากบางครั้งฉันจำเป็นต้องวนซ้ำincludeงาน ฉันอาจเปลี่ยนเป็นincludes เท่านั้น แต่ฉันตัดสินใจเปลี่ยนไปใช้การนำเข้าทุกที่ยกเว้นกรณีที่งานควรจะถูกเรียกใช้หลายครั้ง ฉันตัดสินใจที่จะสัมผัสกับเคสขอบที่ยุ่งยากเหล่านั้นด้วยตัวเอง อาจจะไม่มีใน playbooks ของฉัน หรือหวังว่าฉันจะหาวิธีทำให้มันใช้ได้

UPDเคล็ดลับที่มีประโยชน์อาจสร้างไฟล์งานที่สามารถนำเข้าได้หลายครั้ง แต่ดำเนินการครั้งเดียว :

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

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

...

- name: Set _file_executed
  set_fact:
    _file_executed: True

UPD สิ่งที่ไม่ได้คาดหวังจริงๆของการผสมรวมและการนำเข้าคือการรวมการแทนที่ด้วยการนำเข้า vars:

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

อาจเป็นเพราะinclude_tasksครั้งแรกที่ทำการนำเข้าคงที่เพิ่มเติมทั้งหมดแล้วเปลี่ยนตัวแปรที่ส่งผ่านvarsคำสั่ง

อันที่จริงมันเกิดขึ้นไม่เพียง แต่กับการนำเข้า:

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อีกกรณีของการผสมรวมถึงและนำเข้า

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

เราได้รับtrueและtrueดูกรณีก่อนหน้า (รวม vars สำคัญกว่า vars นำเข้า) 3.ymlดังนั้นเราจึงเปลี่ยนไปรวมถึงใน แต่การรวมในครั้งแรก3.ymlจะถูกข้ามไป เพราะมัน inherites when: httpsจากงานแม่และหลังคาดคะเนจะใช้เวลาจากงานของhttps varsการแก้ปัญหาคือการสลับไปรวมอยู่ใน2.ymlเช่นกัน ที่ป้องกันการแพร่กระจายของwhen: httpsงานลูก


4
คำตอบที่ดี! ฉันรู้สึกหงุดหงิดกับทุกคนบนอินเทอร์เน็ตที่เพิ่งทำซ้ำสิ่งที่เอกสารกล่าว ขอขอบคุณ.
Sergio Acosta
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.