1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Ansible: 一連の処理をノードごとに順次実行させる2つの方法

Last updated at Posted at 2022-11-30

課題: Ansibleにて一連の処理をノードごとに順次実行させたい

一連の処理を、あるノードにて実行、次に別のあるノードにて実行、さらに別のあるノードにて実行、といった順序で処理を行いたい。
通常のプログラミング言語ならば簡単だが、Ansibleでは、blockにループを適用できない為、回避する必要がある。

例えば以下はNG

  - loop: "{{ play_hosts }}"
    when: item == inventory_hostname
    block:
    - debug: msg="{{ inventory_hostname }} step 0"
    - debug: msg="{{ inventory_hostname }} step 1"

ERROR! 'loop' is not a valid attribute for a Block にて失敗

方法1: play単位でserial: 1を使用

serialとは

Playbook例

site0.yml
---
- hosts: all
  gather_facts: false
  serial: 1
  tasks:
  - debug: msg="{{ inventory_hostname }} step 0"
  - debug: msg="{{ inventory_hostname }} step 1"

実行例

$ ansible-playbook -i localhost0,localhost1 -c local site0.yml 

PLAY [all] *************************************************************************************************************

TASK [debug] ***********************************************************************************************************
ok: [localhost0] => {
    "msg": "localhost0 step 0"
}

TASK [debug] ***********************************************************************************************************
ok: [localhost0] => {
    "msg": "localhost0 step 1"
}

PLAY [all] *************************************************************************************************************

TASK [debug] ***********************************************************************************************************
ok: [localhost1] => {
    "msg": "localhost1 step 0"
}

TASK [debug] ***********************************************************************************************************
ok: [localhost1] => {
    "msg": "localhost1 step 1"
}

PLAY RECAP *************************************************************************************************************
localhost0                 : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
localhost1                 : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

ここで、localhost0, localhost1 は、検証用に割り当てたlocalhostの別名

非常にシンプルではあるが、play単位なので小回りは効かない。

taskやblockに対しては、throttle: 1 が利用可能。(ansible2.9 から)
しかし、blockにthrottle: 1をつけた場合、block全体に対する制御ではなく、block内の個別のtaskに対する制御となり、行いたい処理とはならない。

方法2: loop:, when:, include_tasks: を組み合わせて使用

Playbook例

site1.yml
---
- hosts: all
  gather_facts: false
  tasks:

  - loop: "{{ play_hosts }}"
    when: item == inventory_hostname
    include_tasks:
      file: task01.yml
task01.yml
---
- debug: msg="{{ inventory_hostname }} step 0"
- debug: msg="{{ inventory_hostname }} step 1"

実行例

$ ansible-playbook -i localhost0,localhost1 -c local site1.yml 

PLAY [all] *************************************************************************************************************

TASK [include_tasks] ***************************************************************************************************
skipping: [localhost0] => (item=localhost1) 
skipping: [localhost1] => (item=localhost0) 
included: /home/hiroyukionodera/repo/ansible-throttle-include_tasks/task01.yml for localhost0 => (item=localhost0)
included: /home/hiroyukionodera/repo/ansible-throttle-include_tasks/task01.yml for localhost1 => (item=localhost1)

TASK [debug] ***********************************************************************************************************
ok: [localhost0] => {
    "msg": "localhost0 step 0"
}

TASK [debug] ***********************************************************************************************************
ok: [localhost0] => {
    "msg": "localhost0 step 1"
}

TASK [debug] ***********************************************************************************************************
ok: [localhost1] => {
    "msg": "localhost1 step 0"
}

TASK [debug] ***********************************************************************************************************
ok: [localhost1] => {
    "msg": "localhost1 step 1"
}

PLAY RECAP *************************************************************************************************************
localhost0                 : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
localhost1                 : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

意図通りの順序で実行されている。

なお、実際に使用する際には、バッティングのリスクを避ける為、loop変数をitemから変更しておくことをおすすめします。

参考:

コメント

ansible serialでGoogle検索を行うと、この様な状況に対応するための書き込みがいくつかありました。
Task単位の場合には、現在は、問題のあるdelegate_to + run_onceではなく、throttle: 1が使えるというのがAnsibleの進歩でしょうか。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?