Ansible: Playbookの繰り返し制御の色々 (4)

今回もAnsiblePlaybookにおける繰り返し制御について、学んでいきます。

引き続き題材は本家のドキュメントから。

シリーズはこちら。

Ansible: Loops

Do-Until Loops

今回は、今までの繰り返しの指定 with_* という書き方でない繰り返し方です。
プログラムを書いている人には、動作の原理はわかりやすいと思いますが、 Do-Unitl の形式での繰り返しとなります。

つまり、今までは “繰り返しを続ける条件” を書いてきたのですが、これは “繰り返しを終了する条件” を書くイメージとなります。

ドキュメントのサンプルを見てみましょう。

- action:
    shell /usr/bin/foo
  register: result
  until: result.stdout.find("all systems go") != -1
  retries: 5
  delay: 10

ここでは、

  1. shell /usr/bin/foo を実行。
  2. その結果を result という変数に格納。
  3. result の中の標準出力(stdout)の中に “all systems go” が含まれているか確認。
  4. 3.の確認結果、含まれていればそこで終了。
  5. 3.の確認結果、含まれていなければ再び1.からリトライ。この時 delay 秒待つ。
  6. リトライは retries 回失敗したらそこで終了。

という動きになります。

また、 retries はデフォルトで “3”、 delay はデフォルトで “5”、となるようです。

タスク全体としての結果は、最後の実行結果が反映されます。
つまり、上記手順の “4.” で終了すれば “ok” に、 “6.” で終了すると “failed” になります。
リトライが行なわれている場合の、個々の実行結果を確認したい場合には ansible-playbook コマンドを -vv オプション付きで実行すると良さそうです。

また、この until を利用した場合、 変数 result には attempts というキーが追加され、ここにリトライ回数が保持されるようです。

Finding First Matched Files

次は with_first_found です。
これは、ドキュメントにもありますが「滅多に使わないんじゃない?」というもので、少し変わった使い方になります。

正確にはループでは無いのですが、連続して処理をするものなので、似たようなものではあります。

これも、ドキュメントの例を見ながら動きを解説してみます。

- name: INTERFACES | Create Ansible header for /etc/network/interfaces
  template:
    src: "{{ item }}"
    dest: "/etc/foo.conf"
  with_first_found:
    - "{{ ansible_virtualization_type }}_foo.conf"
    - "default_foo.conf"

こちらの例ですと、 with_first_found に書かれた順にファイルを探して、最初に見つかったものを template モジュールに適用する、という動作になります。

そのため、リストの最後に "default_foo.conf" のようにデフォルトで適用するファイルを記載しておくことで、確実にタスクの実行を行なうことができるようになります。

また、これは files paths と組み合わせて複雑な条件でも実行できるようです。

- name: some configuration template
  template:
    src: "{{ item }}"
    dest: "/etc/file.cfg"
    mode: 0444
    owner: "root"
    group: "root"
  with_first_found:
    - files:
       - "{{ inventory_hostname }}/etc/file.cfg"
      paths:
       - ../../../templates.overwrites
       - ../../../templates
    - files:
        - etc/file.cfg
      paths:
        - templates

完全に初見殺しの書き方になっていますね。

filespaths の動作についてはAnsible: Playbookの実行条件制御 when の使い方(3) Selecting Files And Templates Based On Variablesに解説していますので、ご確認ください。

Iterating Over The Results of a Program Execution

こちらも「滅多に使わないんじゃない?」という注意書きのあるものです。
ここでは、「プログラムの実行結果をリストとして扱ってタスクを繰り返し実行する」というやり方が書かれています。

- name: Example of looping over a command result
  shell: "/usr/bin/frobnicate {{ item }}"
  with_lines:
    - "/usr/bin/frobnications_per_host --param {{ inventory_hostname }}"

この例ですと、inventory_hostname に応じて実際に実行するコマンドのオプションを複数生成して繰り返し実行したい、という時に使えることになります。
何言ってんだ、って感じですね。
ちなみに、 frobnications_per_host コマンドは “ローカルマシン”、 frobnicate コマンドは “リモートマシン”、で実行されます。

このように、 inventory に応じて処理分けをしたいならDynamic Inventoryを使った方が良いよ、とドキュメントには書かれています。

また、同じようなことをすべて “リモートマシン”のコマンドで実現する場合には、下記のような書き方になるようです。

- name: Example of looping over a REMOTE command result
  shell: "/usr/bin/something"
  register: command_result

- name: Do something with each result
  shell: "/usr/bin/something_else --param {{ item }}"
  with_items:
    - "{{ command_result.stdout_lines }}"

まとめ

今回取り扱ったものは、だいぶ複雑でイマイチイメージの掴みづらいところだったように思います。
動作を試すのも結構準備が必要そうなので、複雑な繰り返し条件が必要になったときに思い出せるように記録を残しておく、、、という感じになりそうです。

めげずに、残りの項目も翻訳していきたいと思います。

tacck
  • tacck
  • 北の大地の普通のソフトウェアエンジニア。
    インフラ・バックエンド・フロントエンドと、色々やります。

    初心者・若手向けのメンターも希望あればお受けします。

    勉強会運営中
    * ゆるWeb勉強会@札幌
    * スマートスピーカーで遊ぼう会@札幌

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください