前提:Ansible 2.4 から include は非推奨になった
Ansible 2.4 を使っていたら既に嫌というほど見てると思いますが、include を使うと以下のような警告が出るようになりました。
[DEPRECATION WARNING]: The use of 'include' for tasks has been deprecated. Use 'import_tasks' for static inclusions or 'include_tasks' for dynamic inclusions. This feature will be removed in a future release. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
Ansible 2.4 から、いままで include
が持っていた機能は以下の4つのアクションに分けられました。
Action | Operation | Reusable content |
---|---|---|
import_tasks |
static | task |
include_tasks |
dynamic | task |
import_playbook |
static | playbook |
include_playbook |
dynamic | playbook |
include (DEPRECATED) |
both static and dynamic | task or playbook |
この変更は、静的(static)な読み込みと動的(dynamic)な読み込み、そして読み込む対象(task ファイルか playbook ファイルか)を明確に区別することを目的に行われたようです。
static と dynamic の違い
ここで言う static と dynamic の意味は、公式サイトの Creating Reusable Playbooks によると次の通りです。
- 静的な読み込み(static import)は、Playbook をパースする段階で、事前に実行される
- 動的な読み込み(dynamic include)は、タスクを順に処理して、その行に来た段階で実行される
include
は基本的には static import を行いますが、状況によって dynamic include を行うなどして動作がわかりづらいため、Ansible 2.8 で廃止予定とのことです。
じゃあ今までに書いた include
はどうすればいいのか?というと、個人的な意見ですが、特に理由がなければ import_tasks
か import_playbook
に書き換えておけばいい と思います。dynamic include にすると文法ミスの事前検知が行われなくなるので、デバッグが面倒になります。
もっと詳しく知りたい方は、以下のページをどうぞ。@heriet さんによる Qiita の記事は、Ansible 2.2 の時点で書かれたものですが、具体例が多く、基本的な考え方の勉強になりました。
- Including and Importing — Ansible Documentation
- Creating Reusable Playbooks — Ansible Documentation
- include - include a play or task list. — Ansible Documentation
- AnsibleのDynamic IncludeとStatic Include - Qiita
本題:import_tasks/include_tasks に tags を付けた場合の動作
ここまでは前提の話で、ここからやっと本題です。
以下のように import_tasks/include_tasks に tags を付けると、その中に含まれるすべてのタスクに同じタグを付けることができます。これは公式の Tags — Ansible Documentation にも書かれた方法です。
- import_tasks: main.yml tags: [ tag1 ]
- include_tasks: main.yml tags: [ tag1 ]
例えば、main.yml の中身が、
- debug: msg="Task 1" - debug: msg="Task 2"
の場合、ansible-playbook --tags=tag1
で両方のタスクが実行されます。
しかし、何かの理由で Task 2 だけ実行したくなったとします(Ansible 使ってるとよくありますよね?)。そこで、
- debug: msg="Task 1" - debug: msg="Task 2" tags: [ tag2 ]
と直して、ansible-playbook --tags=tag2
を実行すると、include_tasks を使った場合は Task 2 が実行されません。どうやら、以下のような動作の違いがあるようです。
import_tasks
に tags を付けた場合は、「main.yml 内のすべてのタスクに追加するタグ」として扱われるinclude_tasks
に tags を付けた場合は、「include_tasks
アクション自体に追加するタグ」のように扱われる
ローカルホストで実験
ローカルホストで簡単に実験できるのでやってみましょう。Gist にファイルを用意しました。
Example of import_tasks/include_tasks with tags
これらのファイルを同じディレクトリに置いて、以下のように実行してください。
$ ansible-playbook playbook1.yml --tags=tag1
Ansible 2.4.2.0 で実行した結果は、以下の通りです。include_tasks
の場合だけ、tag2 を付けたタスク(Task 2)が無視されているのがわかります。
No. | Playbook | How to import | --tags option |
Task 0 | Task 1 | Task 2 |
---|---|---|---|---|---|---|
1 | playbook1.yml | include | None | ok | ok | ok |
2 | --tags=tag1 |
ok | ok | ok | ||
3 | --tags=tag2 |
- | - | ok | ||
4 | playbook2.yml | import_tasks | None | ok | ok | ok |
5 | --tags=tag1 |
ok | ok | ok | ||
6 | --tags=tag2 |
- | - | ok | ||
7 | playbook3.yml | include_tasks | None | ok | ok | ok |
8 | --tags=tag1 |
ok | ok | ok | ||
9 | --tags=tag2 |
- | - | - |
まとめ:結局どうしたらいいのか?
import_tasks
と include_tasks
を使った場合で、タグの扱いに微妙な違いがあることがわかりました。
上記の結果を見ると、「include_tasks
使うとタグが無視されることがあるのか。使うのやめよう」と思うかもしれません。しかし、以下のように書かれているのに、main.yml 内に tag1 以外のタグがついているというのは、それはそれで可読性に問題があります。
- import_tasks: main.yml tags: [ tag1 ]
そう考えると、結論としては「import_tasks/include_tasks で読み込むタスクにはタグを付けない」というルールを設けるのが良いのではないでしょうか。