include_tasksとimport_tasksの違いは何ですか?


63

Ansible 2.4では、このincludeモジュールは非推奨です。2つの置換モジュールと、その場所で、その船、import_tasksinclude_tasks。しかし、それらは非常に類似した説明を持っています:

  • include_tasks:現在のプレイブックで実行されるタスクのリストを含むファイルが含まれます。
  • import_tasks:後続の実行のために現在のプレイブックに追加されるタスクのリストをインポートします。

前者はいつ使用し、後者はいつ使用する必要がありますか?


(また、非推奨の警告は「動的」タスクと「静的」タスクを指します。ドキュメントを読みましたが、理解できませんでした。)
Ben S

回答:


69

ドキュメントにはこのトピックに関するかなりの部分があります。

主な違いは次のとおりです。

すべてのimport*ステートメントは、プレイブックが解析されるときに前処理されます。
すべてのinclude*ステートメントは、プレイブックの実行中に遭遇したときに処理されます。

だから、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ステートメントの実行時に条件がtrueと評価されたかどうかに基づいて、タスクが存在するかどうかが決まります。私はよく理解していれば...
エセル・エヴァンス

の振る舞いはinclude何ですか?私たちが使用していた場合includeでしょうimport_tasks同等であること?
アンディシン

include持っていたstatic: yes(のように振る舞ったimport_tasks)、およびstatic: no(のようなinclude_tasks)。
コンスタンチンス

のデフォルトはstatic何ですか?
アンディシン

staticNoneデフォルトです:Ansible 2.0以降、タスクインクルードは動的であり、実際のタスクのように動作します。これは、それらをループしたり、スキップしたり、任意のソースの変数を使用したりできることを意味します。Ansibleはこれを自動検出しようとしますが、静的ディレクティブ(Ansible 2.1で追加された)を使用して自動検出をバイパスできます。
コンスタンチンス

15

インポートは静的で、インクルードは動的です。インポートは解析時に行われ、実行時に含まれます。

インポートは基本的に、タスクをファイルのタスクに置き換えます。import_task実行時にありません。だから、のような属性tags、およびwhen(最も可能性の高い他の属性)すべてのインポートタスクにコピーされます。

includesは実際に実行されます。tagsそして、when付属タスクのタスク自体にのみ適用されます。

importタスクがタグ付けされていない場合、インポートされたファイルからタグ付けされたタスクが実行されます。includeタスクにタグが付いていない場合、含まれているファイルからタスクは実行されません。

importタスクがタグ付けされている場合、インポートされたファイルのすべてのタスクが実行されます。includeタスクがタグ付けされている場合、含まれているファイルのタグ付けされたタスクのみが実行されます。

importsの制限:

  • with_*またはloop属性では使用できません
  • 変数に依存する名前のファイルをインポートできません

includesの制限:

  • --list-tags インクルードファイルのタグを表示しません
  • --list-tasks 含まれているファイルのタスクを表示しません
  • notify動的インクルード内からのハンドラー名をトリガーするために使用することはできません
  • --start-at-task動的インクルード内のタスクで実行を開始するために使用することはできません

詳細はこちらこちら

私にとっては、基本的にimportsはループ属性で使用できないという事実に帰着します。

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。したがって、importwhen属性で使用される変数を変更するタスクファイルをインポートすることはできません。

importsで始まるポリシーがありましたincludeが、含まれているファイルまたは含まれているファイルによって何もインポートされていないことを確認する必要があります。しかし、それは維持するのがかなり難しいです。そして、それがトラブルから私を守るかどうかはまだ明らかではありません。推奨されないincludesとimportsの意味、混合。

importときどきincludeタスクをループする必要があるため、s のみを使用することはできません。おそらくincludes のみに切り替えることができます。しかし、タスクが数回実行されることになっている場合を除いて、どこでもインポートに切り替えることにしました。私はこれらすべてのトリッキーなエッジケースを直接体験することにしました。たぶん私のプレイブックには何もないでしょう。またはうまくいけば、私はそれを機能させる方法を見つけるでしょう。

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混合インクルードとインポートの実際に予期されていない効果の1つは、インクルードvarがインポートのものをオーバーライドすることです。

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

を取得truetrue、前のケースを参照してください(include変数はimport変数よりも優先されます)。そのため、インクルードに切り替えます3.yml。ただし、最初のインクルード3.ymlはスキップされます。when: https親タスクから継承し、後者はおそらくhttpsタスクのから取得するためvarsです。解決策は2.yml、同様にインクルードに切り替えることです。これによりwhen: https、子タスクへの伝播が防止されます。


4
素晴らしい答えです!ドキュメントに書かれていることを繰り返すだけで、インターネット上のすべての人にイライラしました。ありがとうございました。
セルジオアコスタ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.