Ansibleのタグを使い始めた際に、継承について知らずにその動作に戸惑ったことがあったのでメモを残しておきます。
今回の記事ではAnsibleのコマンドについては説明していないので、ある程度Ansibleを触っている方が対象になります。
タグの動作検証
最初に、次のようなplaybookを準備します。
---
- hosts: localhost
gather_facts: false
connection: local
tasks:
- name: task1
debug:
msg: task1
tags:
- blue
- name: task2
debug:
msg: task2
tags:
- blue
- green
- name: task3
debug:
msg: task3
tags:
- green
- name: task4
debug:
msg: task4
このplaybookにタグを指定して実行します。ここでは blue を指定します。
$ ansible-playbook --tags=blue playbook.yml
PLAY [localhost] ************************************************************************************
TASK [task1] ****************************************************************************************
ok: [localhost] => {
"msg": "task1"
}
TASK [task2] ****************************************************************************************
ok: [localhost] => {
"msg": "task2"
}
PLAY RECAP ******************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
タグに blue を設定したタスクのみが、実行されているのが確認できます。
次にロールを作成し、同様のタスクをロール下で行うように設定します。
まず、ロールを作成します。
$ ansible-galaxy init --init-path="roles" blue
$ tree
.
├── playbook.yml
└── roles
└── blue
├── README.md
├── defaults
│ └── main.yml
├── files
├── handlers
│ └── main.yml
├── meta
│ └── main.yml
├── tasks
│ └── main.yml
├── templates
├── tests
│ ├── inventory
│ └── test.yml
└── vars
└── main.yml
次にroles/blue/tasks/main.ymlの内容を、先程のplaybookのタスクと同様の内容となるように記述します。
---
# tasks file for blue
- name: task1
debug:
msg: task1
tags:
- blue
- name: task2
debug:
msg: task2
tags:
- blue
- green
- name: task3
debug:
msg: task3
tags:
- green
- name: task4
debug:
msg: task4
playbookの内容を、今作成したロールを実行するように修正します。
---
- hosts: localhost
gather_facts: false
connection: local
roles:
- role: blue
この状態で先程と同様にタグに blue を指定して実行します。
$ ansible-playbook --tags=blue playbook.yml
PLAY [localhost] ************************************************************************************
TASK [blue : task1] *********************************************************************************
ok: [localhost] => {
"msg": "task1"
}
TASK [blue : task2] *********************************************************************************
ok: [localhost] => {
"msg": "task2"
}
PLAY RECAP ******************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
結果も先程と同様で、タグに blue を設定したタスクのみが実行されています。
次にplaybookのロールの設定にタグの設定を追加して、同様のコマンドを実行します。
---
- hosts: localhost
gather_facts: false
connection: local
roles:
- role: blue
tags: blue
$ ansible-playbook --tags=blue playbook.yml
PLAY [localhost] ************************************************************************************
TASK [blue : task1] *********************************************************************************
ok: [localhost] => {
"msg": "task1"
}
TASK [blue : task2] *********************************************************************************
ok: [localhost] => {
"msg": "task2"
}
TASK [blue : task3] *********************************************************************************
ok: [localhost] => {
"msg": "task3"
}
TASK [blue : task4] *********************************************************************************
ok: [localhost] => {
"msg": "task4"
}
PLAY RECAP ******************************************************************************************
localhost : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
すると、タグに blue を設定していないタスクまで実行されているのが確認できます。
タグの継承について
この動作は、Ansibleのユーザーガイドにも記載されている「タグの継承」による動作になります。
タスクのインポートやロールを設定する際に tags: の設定を追加すると、含まれている全てのタスクにタグを追加します。これが「タグの継承」です。
わかるとなるほどと思うのですが、知らずに触っている時は「あれ?」と首を傾げてしまいました。
タグをスキップする際の注意
Ansibleには--skip-tagsオプションを指定して、タグが設定されたタスクをスキップすることができます。
しかしながら「タグの継承」が行われている状況では、このオプションの以下のような特性に注意する必要があります。
- 「タグの継承」が行われてから適用されます。
- --tagsの指定より、--skip-tagsの指定が優先されます。
先程のplaybookに--skip-tagsの指定を追加して実行してみます。
$ ansible-playbook --tags=blue --skip-tags=green playbook.yml
PLAY [localhost] ************************************************************************************
TASK [blue : task1] *********************************************************************************
ok: [localhost] => {
"msg": "task1"
}
TASK [blue : task4] *********************************************************************************
ok: [localhost] => {
"msg": "task4"
}
PLAY RECAP ******************************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
先程までと違い、タスク1とタスク4が実行されています。
- タスク1はblueタグが設定されているので、実行されます。
- タスク2はblueタグとgreenタグが設定されていますが、--skip-tags=greenの指定が優先され実行されません。
- タスク3はgreenタグと「タグの継承」によりblueタグが設定されていますが、--skip-tags=greenの指定が優先され実行されません。
- タスク4は「タグの継承」によりblueタグが自動設定され、実行されます。
タグのスキップは、「タグの継承」と組み合わされると思わぬ動作を引き起こす可能性が出てくるので、注意したいところです。