Ansible Documentation
Handlers: Running Operations On Change
機能
- タスクを実行した結果、対象ホストの状態が変更になった( = changed )ときに一度だけ実行する処理(タスク)
- tasks セクション内の複数のタスクから呼び出された場合でも、handlers セクション内のタスクは一度だけ実行する
- play 内の tasks セクションに含まれるすべてのタスクの実行終了後、handlers セクション内のタスクが一度だけ実行される
- handlers セクション内に複数のタスクが定義されている場合、定義されている順番に実行される
構造
「
シナリオ:CentOS7.6.1810 を minimal インストールしたサーバーの初期設定」で使用した play です。
---
- hosts: all
gather_facts: no
vars_files:
- accounts.yml
- packages.yml
tasks:
- name: グループを作成
group:
name: "{{ item.gname }}"
gid: "{{ item.gid }}"
state: present
loop:
"{{ accounts }}"
- name: ユーザーの作成
user:
name: "{{ item.uname }}"
uid: "{{ item.uid }}"
group: "{{ item.gname }}"
password: "{{ item.password | password_hash('sha512') }}"
state: present
loop:
"{{ accounts }}"
- name: sudoers の設定
template:
src: ./sudoers.j2
dest: /etc/sudoers.d/{{ item.uname }}
mode: 0440
owner: root
group: root
validate: '/usr/sbin/visudo -cf %s'
loop:
"{{ accounts }}"
- name: 追加パッケージのインストール
yum:
name: "{{ item }}"
state: latest
loop:
"{{ packages }}"
- name: 既存パッケージの更新
yum:
name: '*'
state: latest
- name: 再起動
reboot:
play の最後に reboot モジュールで対象ホストを再起動しています。再起動が必要なのは
- 追加パッケージのインストール
- 既存パッケージの更新
の実行結果が changed のときです。
- グループの作成
- ユーザーの作成
- sudoers の設定
上記の 3 つの処理の結果が ok / changed のどちらであっても再起動は不要です。 handlers セクションを使用して play を書き直します。
---
- hosts: all
gather_facts: no
vars_files:
- accounts.yml
- packages.yml
handlers:
- name: 再起動
reboot:
listen: "Managed Node Reboot"
tasks:
- name: グループを作成
group:
name: "{{ item.gname }}"
gid: "{{ item.gid }}"
state: present
loop:
"{{ accounts }}"
- name: ユーザーの作成
user:
name: "{{ item.uname }}"
uid: "{{ item.uid }}"
group: "{{ item.gname }}"
password: "{{ item.password | password_hash('sha512') }}"
state: present
loop:
"{{ accounts }}"
- name: sudoers の設定
template:
src: ./sudoers.j2
dest: /etc/sudoers.d/{{ item.uname }}
mode: 0440
owner: root
group: root
validate: '/usr/sbin/visudo -cf %s'
loop:
"{{ accounts }}"
- name: 追加パッケージのインストール
yum:
name: "{{ item }}"
state: latest
loop:
"{{ packages }}"
notify: "Managed Node Reboot"
- name: 既存パッケージの更新
yum:
name: '*'
state: latest
notify: "Managed Node Reboot"
 tasks セクションと handlers セクションのタスクは notify: と listen: で関連付けします。 notify: でタスクの実行結果が changed のときに実行する handlers セクション内のタスクを指定します。上記の play の実行結果です。
[ansibleman@ansiblesv ansible]$ ansible-playbook -i hosts.yml site.yml
PLAY [all] *********************************************************************
TASK [グループを作成] *****************************************************************
changed: [node-c0706] => (item={u'uname': u'workman', u'password': u'workman@node_c0706', u'gid': 1000, u'uid': 1001, u'gname': u'staff'})
TASK [ユーザーの作成] *****************************************************************
changed: [node-c0706] => (item={u'uname': u'workman', u'password': u'workman@node_c0706', u'gid': 1000, u'uid': 1001, u'gname': u'staff'})
TASK [sudoers の設定] *************************************************************
changed: [node-c0706] => (item={u'uname': u'workman', u'password': u'workman@node_c0706', u'gid': 1000, u'uid': 1001, u'gname': u'staff'})
TASK [追加パッケージのインストール] **********************************************************
changed: [node-c0706] => (item=open-vm-tools)
TASK [既存パッケージの更新] **************************************************************
changed: [node-c0706]
RUNNING HANDLER [再起動] **********************************************************
changed: [node-c0706]
PLAY RECAP *********************************************************************
node-c0706 : ok=6 changed=6 unreachable=0 failed=0
[ansibleman@ansiblesv ansible]$
handlers セクションは何回呼び出されても実行は一度だけです。「追加パッケージのインストール」と「既存パッケージの更新」で handlers セクション内のタスクを呼び出していますが、「再起動」は 1 回だけ実行しています。
次は Ansible Documentaion に記載されている例です。
handlers:
- name: restart memcached
service:
name: memcached
state: restarted
listen: "restart web services"
- name: restart apache
service:
name: apache
state:restarted
listen: "restart web services"
tasks:
- name: restart everything
command: echo "this task will restart the web services"
notify: "restart web services"
この例は tasks セクションの「 restart everything 」の実行結果が changed の場合、handlers セクション内の「 restart memcached 」と「 restart apache 」の 2 つのタスクを実行します。このように tasks セクションと handlers セクションのタスクの組み合わせは 1 : 1 、1 : n 、n : 1 のいずれでも可能です。