2
3

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 5 years have passed since last update.

Tips: Ansibleにおけるwhile, until処理

Last updated at Posted at 2020-03-27

Ansibleによる単一のタスクに対するループ(until)

-
  until: r.stdout|int <= 0
  shell: |
    NEW=$(( $(cat NUM) - 1 ))
    echo $NEW > NUM
    cat NUM
  register: r
  retries: 10
  delay: 0

この例では、shellタスクのstdoutが0以下になるまで、もしくは最大でretries:指定の10回まで処理を繰り返します。
終了条件には、shellモジュールならばコマンドのstdout, stderr, rcなど、register変数に設定される値が使用可能です。
retries:は最大リトライ回数で、省略可能ですがデフォルトは3回とかなり少ない為、余裕を持った指定が必要です。
delay:はループの待ち時間(秒)でデフォルトは1(秒)です。
breakは、until:の条件を満たす事で対応可能です。例えば上の例の場合、echo 0; exit などとすればこのタスクを抜ける事ができます。

コマンド実行結果を判断に使用する為、until:の条件を満たしていても最初の1回は実行されます。

NUM初期値が5の場合の出力例

TASK [shell] *******************************************************************
FAILED - RETRYING: command (10 retries left).
FAILED - RETRYING: command (9 retries left).
FAILED - RETRYING: command (8 retries left).
FAILED - RETRYING: command (7 retries left).
changed: [localhost]

5回実行。
untilの条件を満たす事ができなかった回はFAILEDと表示される。5回目に成功して、changed: が出力されている。
retries:の回数内で成功しなかった場合にはtaskそのものがfailedとなる。
実行後のNUMは0。

NUM初期値が1の場合の出力例

TASK [shell] *******************************************************************
changed: [localhost]

1回実行。
実行後のNUMは0。

NUM初期値が0の場合の出力例

TASK [shell] *******************************************************************
changed: [localhost]

untilの為、1回は実行されてしまう。
実行後のNUMは-1。

Ansibleによる単一のタスクに対するループ(while)

通常のプログラミング言語におけるwhileループ、即ち、初回実行に関しても条件による実施判断を行わせるには、例えば以下の様に、事前に情報収拾を行い、when:により判断させる対応が可能でしょう。

-
  shell: |
    cat ./NUM
  register: r0
  changed_when: false

-
  when: not r0.stdout|int <= 0
  until:    r1.stdout|int <= 0
  shell: |
    NEW=$(( $(cat ./NUM) - 1 ))
    echo $NEW > ./NUM
    cat ./NUM
  register: r1
  retries: 10
  delay: 0

この例では判り易さの為にr0, r1とregister変数を分けていますが、上書きされるので同じ変数を再利用可能です。

NUM初期値が0(もしくは負)の場合の出力例

TASK [shell] *******************************************************************
skipping: [localhost]

0回実行(skip)
実行後のNUMは変更なし。

ブロックに対するループ

untilやloop:などは個別のタスクに対してのみ指定可能であり、taskを集めたblock:に対して実施できないという制約があります。(エラーとなります。)
また、個別のタスクに複数のループを指定できない事から、そのままでは任意の多重ループに関しても実現できません。
この状況を回避するには、以下の様な対応が可能です。

  • 別ファイルに分けたロジックを動的に読み込むinclude_tasks:などに対してループを行う

静的に読み込むimport_tasksなどは使用できない為、制約などがありうる事に注意が必要です。

公式: Tradeoffs and Pitfalls Between Includes and Imports

2
3
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
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?