0
0

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

Ansible Tips: shellモジュールで長時間かかる処理を行う際に、随時途中経過ログを出力させる

Last updated at Posted at 2021-07-09

shellモジュールで途中経過を出力させる

terraformのapplyなど、長時間かかる処理を、Ansibleのshellモジュールで実行すると、Ansibleのログ表示が20分など長時間停止してしまい、エラーが出ていたとしてもその認識に不必要に時間がかかってしまったりする。
あまり美しくない実装でも構わないので、準リアルタイムで出力表示させたい。
試行錯誤の末、以下のようにすることで表示できている。

実装概要

処理をバックグラウンドで実行させ、実行ログはターゲットノード上のファイルに出力させる。
その上で、Ansible Playbookでは、一定時間おきに上のログファイルの内容をAnsibleのログとして出力。

途中経過表示サンプル

tasks
  - set_fact:
      shell_log: "/tmp/shell.{{ lookup('pipe','date +%Y%m%d%H%M%S') }}.log"

  - name: terraform apply -auto-approve
    shell: |-
      {   
      set -ex 
      exec > {{shell_log}} 2>&1
      terraform init -no-color
      terraform apply -auto-approve -no-color || terraform apply -auto-approve -no-color
      echo __END__
      } & 
    poll: 0

  - pause:
      seconds: 1

  - shell: cat {{shell_log}}
    register: tail

  - loop: "{{ range(tail_times)|list }}"
    when: tail is not skipped and tail.stdout_lines|last != '__END__'
    shell: |
      sleep {{ tail_seconds }}
      cat {{shell_log}}
    register: tail
    vars:
      tail_times: 10
      tail_seconds: 5

  - file:
      path: "{{shell_log}}"
      state: absent

なお、以下を使う事でAnsible側にもログを残すことが可能。
https://qiita.com/hiroyuki_onodera/items/c36ba00da414d9df7e4e

ansible.cfg
[defaults]
verbosity = 1 
stdout_callback = debug

この設定により、shellモジュールのみでログへの出力が可能となり、loop対象を1モジュールとできることからinclude_tasksなどで分離することも不要とできる。

途中経過表示サンプル(旧)

30秒おきに実行中のログをansibleのdebugモジュールで表示

tasks
  - set_fact:
      shell_log: "/tmp/shell.{{ lookup('pipe','date +%Y%m%d%H%M%S') }}.log"

  - name: terraform apply -auto-approve
    shell: |-
      {   
      set -ex 
      exec > {{shell_log}} 2>&1
      terraform init -no-color
      terraform apply -auto-approve -no-color || terraform apply -auto-approve -no-color
      echo __END__
      } & 
    poll: 0

  - pause:
      seconds: 1

  - shell: cat {{shell_log}}
    register: tail

  - include_tasks: tail.yml
    loop: "{{ range(tail_times)|list }}"
    vars:
      tail_times: 60    # この場合、最大 60 回 * 30 秒 = 30分間 監視し、次の処理に進む
      tail_seconds: 30

  - shell: cat {{shell_log}}
    register: tail

  - debug: { var: tail.stdout_lines }

  - file:
      path: "{{shell_log}}"
      state: absent
tail.yml
---
- when: tail is not skipped and tail.stdout_lines|last != '__END__'
  block:

  - pause:
      seconds: "{{tail_seconds}}"

  - shell: cat {{shell_log}}
    register: tail

  - debug: { var: tail.stdout_lines }

最終行が __END__ となると、以降はskipされる。

サンプルの制約

  • エラー処理は未実装
    • 時間切れ処理
    • スクリプト実行中にエラーとなった場合の処理 (トラップにて対応可能でしょう)
0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?