目次
3.3 include と include_tasks の違い
4.2 import_tasks と include_tasks の違い
4.3 import/include ハンドラに関する注意事項
I.はじめに
すべてのタスクを整理するためにプレイブック ファイルを使用しています。しかし、プロジェクトが大きくなり、タスクがどんどん増えてくると、すべてのタスクを Playbook に書き込んでしまうと、可読性が悪くなってしまうので、この時点で Playbook を再編成する必要があります。
したがって、大きな Playbook をいくつかの小さな Playbook ファイルに分割することができ、これらの断片化された小さなファイルをメイン構成ファイルに導入することができます。
2. イントロダクションを含める
ansible playbook の include 機能は、 include キーワードを直接使用することです。
2.1 インポート タスクを含める
通常、大きな Playbook を作成すると、複数の Playbook に同じタスクがいくつか含まれますが、このとき、同じタスクを yml ファイルに個別に抽出し、include でインポートできます。
例: Playbook を使用して lnmp とランプをインストールする
インストールランプ
# [root@clinet ~]# cat lamp.yml
‐ hosts: test
gather_facts: no
tasks:
‐ name: install mysql
package:
name: mysql
state: present
- name: install php-fpm
package:
name: php‐fpm
state: present
- name: install httpd
package:
name: httpd
state: present
lnmp をインストールする
#[root@clinet ~]# cat lnmp.yml
‐ hosts: test
gather_facts: no
tasks:
‐ name: install mysql
package:
name: mysql
state: present
- name: install php-fpm
package:
name: php‐fpm
state: present
- name: install httpd
package:
name: nginx
state: present
上記の 2 つのインストール方法から、関連するタスクは同じであることがわかります。つまり、mysql のインストールと php-fpm のインストールです。したがって、これら 2 つのタスクを yml ファイルに書き込むことができます。
#[root@clinet ~]#cat install_sq_php.yml
‐ name: install mysql
package:
name: mysql
state: present
- name: install php-fpm
package:
name: php‐fpm
state: present
使用方法は次のとおりです。
#[root@clinet ~]# cat lnmp.yml
‐ hosts: test
gather_facts: no
tasks:
‐ name: install mysql and php
include: install_sq_php.yml #一般写绝对路径
- name: install httpd
package:
name: nginx
state: present
#[root@clinet ~]# cat lamp.yml
‐ hosts: test
gather_facts: no
tasks:
‐ name: install mysql and php
include: install_sq_php.yml #一般写绝对路径
- name: install httpd
package:
name: httpd
state: present
2.2 インクルード時に変数をインポートする
方法 1: include で yml ファイルを導入する場合、値を yml 変数でファイルに直接渡す
[root@clinet include]# cat user.yml
- name: debug user name info
debug:
msg: my name is '{
{ user }}'
[root@clinet include]#
[root@clinet include]#
[root@clinet include]# cat include_user.yml
- hosts: test
gather_facts: no
tasks:
- name: include user yaml file1
include: /root/ansible_test/ansible_2/yum_file/include/user.yml user=xhz
- name: include user yaml file2
include: /root/ansible_test/ansible_2/yum_file/include/user.yml user=flf
- name: include user yaml file2
include: /root/ansible_test/ansible_2/yum_file/include/user.yml user=zzzz
[root@clinet include]#
方法 2: vars を使用して変数を定義する
[root@clinet include]# cat user.yml
- name: debug user name info
debug:
msg: my name is '{
{ user }}'
[root@clinet include]#
[root@clinet include]#
[root@clinet include]# cat include_user2.yml
- hosts: test
gather_facts: no
vars:
user: ehoweh
tasks:
- name: include user yaml file1
include: /root/ansible_test/ansible_2/yum_file/include/user.yml
[root@clinet include]#
[root@clinet include]#
方法 3: include がタスク yml ファイルをインポートする場合、vars キーワードを使用して定義します。
[root@clinet include]# cat user.yml
- name: debug user name info
debug:
msg: my name is '{
{ user }}'
[root@clinet include]#
[root@clinet include]#
[root@clinet include]# cat include_user2.yml
- hosts: test
gather_facts: no
tasks:
- name: include user yaml file1
include: /root/ansible_test/ansible_2/yum_file/include/user.yml
vars:
user: xhz123
[root@clinet include]#
[root@clinet include]#
[root@clinet include]#
タグを使用して含まれる 2.3
インクルードで導入されたタスクファイルには複数のタスクがあります.インクルードにラベルを付けて指定されたラベルでインクルードを実行すると、この時点でインポートされたタスクファイル内のすべてのタスクが対象になります. (つまり、タスク ファイル内のすべてのタスクが実行されます)
[root@clinet include]# cat user.yml
- name: debug user name info
debug:
msg: my name is '{
{ user }}'
- name: debug
debug:
msg: "{
{ user }}"
[root@clinet include]#
[root@clinet include]#
[root@clinet include]# cat include_user2.yml
- hosts: test
gather_facts: no
tasks:
- name: include user yaml file1
include: /root/ansible_test/ansible_2/yum_file/include/user.yml
vars:
user: xhz123
tags: t1
[root@clinet include]#
[root@clinet include]#
[root@clinet include]#
2.4 インクルードでのループの使用
インクルード (特別なタスク) でループを使用する場合と前のタスク ループを使用する場合に違いはありませんが、インクルードで使用されるループ変数は、インポートされたタスク ファイルで呼び出されます。
[root@clinet include]# cat user.yml
- name: debug
debug:
msg: "{
{ item.key }} {
{ item.value.name }} {
{ item.value.passwd }}"
loop: "{
{user | dict2items }}"
[root@clinet include]#
[root@clinet include]#
[root@clinet include]# cat include_user2.yml
- hosts: test
gather_facts: no
tasks:
- name: include user yaml file1
include: /root/ansible_test/ansible_2/yum_file/include/user.yml
vars:
user:
xhz1:
name: xiaohaizhou
passwd: 123
flf:
name: fulifang
passwd: 456
[root@clinet include]#
[root@clinet include]#
上の例ではインクルード下でループサイクルをアンインストールしていますが、考えてみると、インポートしたyamlファイルとインクルード下にループサイクルがある場合、このときインポートしたyamlファイルの変数呼び出しはどちらを使うのでしょうか? 例は次のとおりです。
インポートされた yaml ファイル:
[root@clinet include]# cat user.yml
- name: debug
debug:
msg: "{
{ item }}"
loop: ['xhz1','xhz2','xhz3']
[root@clinet include]#
[root@clinet include]#
インクルードyamlファイルを実行
[root@clinet include]# cat include_user2.yml
- hosts: test
gather_facts: no
tasks:
- name: include user yaml file1
include: /root/ansible_test/ansible_2/yum_file/include/user.yml
loop: ['flf1','flf2','flf3']
[root@clinet include]#
実行結果は次のとおりです。
[root@clinet ansible_2]# ansible-playbook yum_file/include/include_user2.yml
PLAY [test] *********************************************************************************************************************************************************************************************
TASK [include user yaml file1] **************************************************************************************************************************************************************************
included: /root/ansible_test/ansible_2/yum_file/include/user.yml for 192.168.194.129
included: /root/ansible_test/ansible_2/yum_file/include/user.yml for 192.168.194.129
included: /root/ansible_test/ansible_2/yum_file/include/user.yml for 192.168.194.129
TASK [debug] ********************************************************************************************************************************************************************************************
[WARNING]: The loop variable 'item' is already in use. You should set the `loop_var` value in the `loop_control` option for the task to something else to avoid variable collisions and unexpected
behavior.
ok: [192.168.194.129] => (item=xhz1) => {
"msg": "xhz1"
}
ok: [192.168.194.129] => (item=xhz2) => {
"msg": "xhz2"
}
TASK [debug] ********************************************************************************************************************************************************************************************
[WARNING]: The loop variable 'item' is already in use. You should set the `loop_var` value in the `loop_control` option for the task to something else to avoid variable collisions and unexpected
behavior.
ok: [192.168.194.129] => (item=xhz1) => {
"msg": "xhz1"
}
ok: [192.168.194.129] => (item=xhz2) => {
"msg": "xhz2"
}
TASK [debug] ********************************************************************************************************************************************************************************************
[WARNING]: The loop variable 'item' is already in use. You should set the `loop_var` value in the `loop_control` option for the task to something else to avoid variable collisions and unexpected
behavior.
ok: [192.168.194.129] => (item=xhz1) => {
"msg": "xhz1"
}
ok: [192.168.194.129] => (item=xhz2) => {
"msg": "xhz2"
}
PLAY RECAP **********************************************************************************************************************************************************************************************
192.168.194.129 : ok=6 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@clinet ansible_2]#
結論は:
実行されたインクルード yaml ファイルとインクルード yaml ファイルの両方にループがある場合、変数はインクルード yaml ファイルの値を使用します。
loop_control キーワードを使用して、インクルード yaml ファイルの変数値を呼び出すようにします。
インポートされた yaml ファイル:
[root@clinet include]# cat user.yml
- name: debug
debug:
msg: "{
{ other_item1 }}"
loop: ['xhz1','xhz2','xhz3']
[root@clinet include]#
[root@clinet include]#
実行されたインクルード ファイル:
[root@clinet include]# cat include_user2.yml
- hosts: test
gather_facts: no
tasks:
- name: include user yaml file1
include: /root/ansible_test/ansible_2/yum_file/include/user.yml
loop: ['flf1','flf2','flf3']
loop_control:
loop_var: outer_item1
[root@clinet include]#
以下の結果:
[root@clinet ansible_2]# ansible-playbook yum_file/include/include_user2.yml
PLAY [test] *********************************************************************************************************************************************************************************************
TASK [include user yaml file1] **************************************************************************************************************************************************************************
included: /root/ansible_test/ansible_2/yum_file/include/user.yml for 192.168.194.129
included: /root/ansible_test/ansible_2/yum_file/include/user.yml for 192.168.194.129
included: /root/ansible_test/ansible_2/yum_file/include/user.yml for 192.168.194.129
TASK [debug] ********************************************************************************************************************************************************************************************
ok: [192.168.194.129] => (item=xhz1) => {
"msg": "flf1"
}
ok: [192.168.194.129] => (item=xhz2) => {
"msg": "flf1"
}
ok: [192.168.194.129] => (item=xhz2) => {
"msg": "flf1"
}
TASK [debug] ********************************************************************************************************************************************************************************************
ok: [192.168.194.129] => (item=xhz1) => {
"msg": "flf2"
}
ok: [192.168.194.129] => (item=xhz2) => {
"msg": "flf2"
}
ok: [192.168.194.129] => (item=xhz2) => {
"msg": "flf2"
}
TASK [debug] ********************************************************************************************************************************************************************************************
ok: [192.168.194.129] => (item=xhz1) => {
"msg": "flf3"
}
ok: [192.168.194.129] => (item=xhz2) => {
"msg": "flf3"
}
ok: [192.168.194.129] => (item=xhz2) => {
"msg": "flf3"
}
PLAY RECAP **********************************************************************************************************************************************************************************************
192.168.194.129 : ok=6 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@clinet ansible_2]#
ご覧のとおり、outer_item の値は、外側のループの item の値とまったく同じです。この二重ループが発生した場合、外側のループで loop_var オプションを使用して変数を指定し、外側のループで item 変数を置き換えるために使用することで、外側のループでアイテムの値を取得できます。内側のループで、2 つのループで項目変数名の競合を回避します。
2.5 使用条件判定を含む
条件が真の場合、include ステートメントが実行されます。
[root@clinet include]# cat user.yml
- name: debug
debug:
msg: "{
{ item.key }} {
{ item.value.name }} {
{ item.value.passwd }}"
loop: "{
{user | dict2items }}"
[root@clinet include]#
[root@clinet include]#
[root@clinet include]# cat include_user2.yml
- hosts: test
gather_facts: no
tasks:
- name: include user yaml file1
include: /root/ansible_test/ansible_2/yum_file/include/user.yml
vars:
user:
xhz1:
name: xiaohaizhou
passwd: 123
flf:
name: fulifang
passwd: 456
when: 1 > 2
[root@clinet include]#
[root@clinet include]#
2.6 インポート ハンドラを含める
ハンドラー インクルードは、タスク インクルードとほぼ同じです。つまり、ハンラーによって実行されるタスクは、yaml ファイルに書き込まれ、ハンドラーの下のインクルードを通じてインポートされます。例は次のとおりです。
[root@clinet include]# cat handler.yml
- name: restart apache
service:
name: apache
state: restarted
[root@clinet include]#
[root@clinet include]#
[root@clinet include]# cat include_handler.yml
- hosts: test
gather_facts: no
tasks:
.....
handlers:
- name: include user yaml file1
include: /root/ansible_test/ansible_2/yum_file/include/handler.yml
[root@clinet include]#
2.7 インポート プレイブックを含める
include を使用して Playbook を別の Playbook にインポートします。
[root@clinet include]# cat include_handler.yml
- hosts: test
gather_facts: no
tasks:
- name: include playbook
include: /root/ansible_test/ansible_2/yum_file/include/playbook.yml
3. Include_tasks の紹介
3.1 include_tasks の基本的な使い方
インクルードの使用については以前に詳しく説明しましたが、実際には、インクルード構文は ansible の後続のバージョンで非推奨になる可能性があります。また、include の元の使用法を置き換えるためにいくつかの新しいキーワードを使用します。include_tasks はその 1 つです。
include を使用して、タスク、ハンドラー、プレイブックなどを含めることができます。また、include_tasks は、タスクを含む yaml ファイルをインポートするために特別に使用されます。
[root@clinet include]# cat user.yml
- name: debug info1
debug:
msg: "task1 in user.yaml"
- name: debug info2
debug:
msg: "task2 in user.yaml"
[root@clinet include]#
[root@clinet include]#
[root@clinet include]# cat include_user2.yml
- hosts: test
gather_facts: no
tasks:
- name: xhz1
debug:
msg: 'task1'
- name: include
include_tasks: ./user.yml
- name: xhz2
debug:
msg: 'task2'
[root@clinet include]#
include_tasks还可以写成
- name: include info
include_tasks:
file: ./user.yml
の結果
[root@clinet ansible_2]# ansible-playbook yum_file/include/include_user2.yml
PLAY [test] *********************************************************************************************************************************************************************************************
TASK [xhz1] *********************************************************************************************************************************************************************************************
ok: [192.168.194.129] => {
"msg": "task1"
}
TASK [include] ******************************************************************************************************************************************************************************************
included: /root/ansible_test/ansible_2/yum_file/include/user.yml for 192.168.194.129
TASK [debug info1] **************************************************************************************************************************************************************************************
ok: [192.168.194.129] => {
"msg": "task1 in user.yaml"
}
TASK [debug info2] **************************************************************************************************************************************************************************************
ok: [192.168.194.129] => {
"msg": "task2 in user.yaml"
}
TASK [xhz2] *********************************************************************************************************************************************************************************************
ok: [192.168.194.129] => {
"msg": "task2"
}
PLAY RECAP **********************************************************************************************************************************************************************************************
192.168.194.129 : ok=5 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@clinet ansible_2]#
include_tasksを使用すると、include_tasks 自体がタスクと見なされ、このタスクがインクルード ファイルのパスをコンソールに出力することがわかります。これは、include_tasks と include の違いです 。include は透過的ですが、 include_tasks は visible です。include_tasks はよりタスクに似ており、このタスクには他のタスクが含まれています。
3.2 include_tasks でのタグの使用
前述したように、インクルードにタグを追加すると、タグはインクルード内のすべてのタスクに対して有効になります。つまり、include に対応するタグが呼び出されると、include ファイル内のすべてのタスクが実行されます。
ただし、include_tasks にタグを追加しても、include_tasks 自体にのみ有効であり、include_tasks 内のすべてのタスクが有効になるわけではありません。
[root@clinet include]# cat user.yml
- name: debug info1
debug:
msg: "task1 in user.yaml"
- name: debug info2
debug:
msg: "task2 in user.yaml"
[root@clinet include]#
[root@clinet include]#
[root@clinet include]# cat include_user2.yml
- hosts: test
gather_facts: no
tasks:
- name: xhz1
debug:
msg: 'task1'
- name: include
include_tasks: ./user.yml
tags: t1
- name: xhz2
debug:
msg: 'task2'
[root@clinet include]#
の結果
[root@clinet ansible_2]# ansible-playbook yum_file/include/include_user2.yml --tags=t1
PLAY [test] *********************************************************************************************************************************************************************************************
TASK [include] ******************************************************************************************************************************************************************************************
included: /root/ansible_test/ansible_2/yum_file/include/user.yml for 192.168.194.129
PLAY RECAP **********************************************************************************************************************************************************************************************
192.168.194.129 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@clinet ansible_2]#
タグを include_tasks に含まれるすべてのタスクで有効にしたい場合は、include_tasks モジュールの apply パラメータを使用して、tags: always 組み込みタグと連携する必要があります。
[root@clinet include]# cat include_user2.yml
- hosts: test
gather_facts: no
tasks:
- name: xhz1
debug:
msg: 'task1'
- name: include
include_tasks:
file: ./user.yml
apply:
tags: t1
tags: always
- name: xhz2
debug:
msg: 'task2'
[root@clinet include]#
[root@clinet include]#
以下の結果:
[root@clinet ansible_2]# ansible-playbook yum_file/include/include_user2.yml --tags=t1
PLAY [test] *********************************************************************************************************************************************************************************************
TASK [include] ******************************************************************************************************************************************************************************************
included: /root/ansible_test/ansible_2/yum_file/include/user.yml for 192.168.194.129
TASK [debug info1] **************************************************************************************************************************************************************************************
ok: [192.168.194.129] => {
"msg": "task1 in user.yaml"
}
TASK [debug info2] **************************************************************************************************************************************************************************************
ok: [192.168.194.129] => {
"msg": "task2 in user.yaml"
}
PLAY RECAP **********************************************************************************************************************************************************************************************
192.168.194.129 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@clinet ansible_2]#
ここで、tags:always タグは include_tasks 自体に対してのみ有効であることに注意してください。つまり、他のタスクのタグが呼び出された場合、include_tasks 自体は呼び出されますが、それに含まれるタスクは呼び出されません。
たとえば、always タグを直接呼び出すと、include_tasks が呼び出されますが、そこに含まれるタスクは呼び出されず、実行結果は次のようになります。
[root@clinet ansible_2]# ansible-playbook yum_file/include/include_user2.yml --tags=always
PLAY [test] *********************************************************************************************************************************************************************************************
TASK [include] ******************************************************************************************************************************************************************************************
included: /root/ansible_test/ansible_2/yum_file/include/user.yml for 192.168.194.129
PLAY RECAP **********************************************************************************************************************************************************************************************
192.168.194.129 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@clinet ansible_2]#
[root@clinet ansible_2]#
それに含まれるタスクが常に呼び出されるようにするには、always ラベルを追加して適用する必要があります。次のように構成を変更できます。
[root@clinet include]# cat include_user2.yml
- hosts: test
gather_facts: no
tasks:
- name: xhz1
debug:
msg: 'task1'
- name: include
include_tasks:
file: ./user.yml
apply:
tags: t1,always
tags: always
- name: xhz2
debug:
msg: 'task2'
[root@clinet include]#
実行結果は次のとおりです。
[root@clinet ansible_2]# ansible-playbook yum_file/include/include_user2.yml --tags=always
PLAY [test] *********************************************************************************************************************************************************************************************
TASK [include] ******************************************************************************************************************************************************************************************
included: /root/ansible_test/ansible_2/yum_file/include/user.yml for 192.168.194.129
TASK [debug info1] **************************************************************************************************************************************************************************************
ok: [192.168.194.129] => {
"msg": "task1 in user.yaml"
}
TASK [debug info2] **************************************************************************************************************************************************************************************
ok: [192.168.194.129] => {
"msg": "task2 in user.yaml"
}
PLAY RECAP **********************************************************************************************************************************************************************************************
192.168.194.129 : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@clinet ansible_2]#
3.3 include と include_tasks の違い
1. インクルードは透過的で、インクルードのファイル パスはコンソールに出力されませんが、include_tasks は表示され、ファイル パスはコンソールに出力されます。
2. include 用に追加されたタグは、include 内のすべてのタスクに対してタグが有効になりますが、include_tasks は include_tasks 内のすべてのタスクに対して有効になるわけではないため、apply パラメータと always built-in タグの連携が必要です。 .
4. import_tasks の紹介
4.1 import_tasks の使用
import_tasks は include_tasks に似ていますが、キーワードを import_tasks に変更するだけです。
[root@clinet include]# cat include_user.yml
- hosts: test
gather_facts: no
tasks:
- name: include user yaml file1
include: /root/ansible_test/ansible_2/yum_file/include/user.yml
vars:
user: xhz
[root@clinet include]#
[root@clinet include]# cat user.yml
- name: debug user info
debug:
msg: "{
{ user }}"
[root@clinet include]#
[root@clinet include]#
以下の結果:
[root@clinet ansible_2]# ansible-playbook yum_file/include/include_user.yml
PLAY [test] *********************************************************************************************************************************************************************************************
TASK [debug user info] **********************************************************************************************************************************************************************************
ok: [192.168.194.129] => {
"msg": "xhz"
}
PLAY RECAP **********************************************************************************************************************************************************************************************
192.168.194.129 : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@clinet ansible_2]#
import_tasks モジュールは、比較的透過的な include_tasks モジュールのように、コンソールに独自のタスク情報を出力しないことがわかります。
4.2 import_tasks と include_tasks の違い
1. import_tasks モジュールは、include_tasks モジュールのように、コンソールに独自のタスク情報とタスク パスを出力しません。
2. import_tasks は静的で、インポートされたファイルは Playbook のロード時に前処理されますが、include_tasks は動的で、含まれるファイルは Playbook の実行時にのみ処理されます。
3. 含まれているタスク リストでループ操作を実行する場合は、include_tasks のみを使用できます。import_tasks はループ操作をサポートしていません。つまり、loop や with_X を使用してインクルード ファイルをループする場合、include_tasks でのみ正常に使用できます。
4. when を使用して条件付き判定をインクルード ファイルに追加する場合、include_tasks と import_tasks は根本的に異なります。・include_tasks に when を使用する場合、when に対応する条件は include_tasks タスク自体にのみ適用され、含まれるタスクが実行されると、これらの含まれるタスクに対して条件が再判定されることはありません。
・import_tasks に when を使用すると、インポートされたファイル内の各タスクに when に対応する条件が適用され、インポートされたタスクが実行されると、含まれるタスクごとに同じ条件が判定されます。
したがって、include を使用するか、include_tasks を使用するか、import_tasks を使用するかで迷った場合は、include_tasks を直接使用するのが適切であり、include と import_tasks の存在を忘れることさえできます。
4.3 import/include ハンドラに関する注意事項
ハンドラーでの実行は実際にはタスクですが、トリガーされたときにのみ実行されるため、ハンドラーでタスクをインポートする場合は、include_tasks と import_tasks を直接使用することもできます。include_handlers についての言及はありません。したがって、統一されたステートメント: include_tasks を直接使用する