Ansible Tips: taskがエラーとなった場合などの結果出力を劇的に読みやすくする設定(stdout_callback = debug)



#### サマリー

ansible.cfg の[defaults]に**stdout_callback = debug** (や **yaml** )を設定すると、タスク失敗時などのansible-playbookログ表示が読みやすくなる。
(ただしyamlは日本語表示に問題がある可能性)

#### 追記 2022/04: 前提コレクションの導入


おそらくansible core 2.10以降では、これらはコレクションに移動していて、コレクションの導入が必要となっています。(ansible [core 2.12.3]にて確認)

```
ansible-galaxy collection install ansible.posix      # stdout_callback = ansible.posix.debug用
ansible-galaxy collection install community.general  # stdout_callback = community.general.yaml用
```

指定時にもフルネームで指定した方がより良いでしょう。

```ini:ansible.cfg
[defaults]
verbosity = 1
stdout_callback = ansible.posix.debug
# stdout_callback = community.general.yaml
```

参考:
https://twitter.com/akira6592/status/1268177439206694912

#### プレイブック例


```yaml:site.yml
- hosts: all
  gather_facts: false
  tasks:

  - name: 日本語複数行出力
    shell: |
      echo "あいうえお
      かきくけこ"

  - name: 日本語複数行出力後にエラー
    shell: |
      echo "あいうえお
      かきくけこ"
      exit 99
```

2つ目のtaskではexit 99にてエラーとして終了させる

#### ansible.cfgでの指定なし

```
# ansible-playbook -i localhost, -c local site.yml

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

TASK [日本語複数行出力] **************************************************************************************************
changed: [localhost]

TASK [日本語複数行出力後にエラー] ****************************************************************************************
fatal: [localhost]: FAILED! => {"changed": true, "cmd": "echo \"あいうえお\nかきくけこ\"\nexit 99\n", "delta": "0:00:00.002494", "end": "2021-07-15 22:10:05.189742", "msg": "non-zero return code", "rc": 99, "start": "2021-07-15 22:10:05.187248", "stderr": "", "stderr_lines": [], "stdout": "あいうえお\nかきくけこ", "stdout_lines": ["あいうえお", "かきくけこ"]}

PLAY RECAP **************************************************************************************************************
localhost                  : ok=1    changed=1    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0
```
正常終了した場合には結果詳細が表示されない。
エラーで終わった場合には結果詳細が表示されるが、可読性が悪い。




#### ansible.cfg にてverbosity = 1とstdout_callback = debugを設定

```ini:ansible.cfg
[defaults]
verbosity = 1
stdout_callback = debug
```

verbosity = 1 は -v相当。これにより、成功時にも結果詳細を表示させる。
stdout_callback = debugにて、結果詳細をフォーマットされたJSONとして表示させる。
 

```
# ansible-playbook -i localhost, -c local site.yml
Using /root/roles/jp-stdout_callback/ansible.cfg as config file

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

TASK [日本語複数行出力] **************************************************************************************************
changed: [localhost] => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "cmd": "echo \"あいうえお\nかきくけこ\"\n",
    "delta": "0:00:00.002483",
    "end": "2021-07-15 22:12:55.306966",
    "rc": 0,
    "start": "2021-07-15 22:12:55.304483"
}

STDOUT:

あいうえお
かきくけこ

TASK [日本語複数行出力後にエラー] ****************************************************************************************
fatal: [localhost]: FAILED! => {
    "changed": true,
    "cmd": "echo \"あいうえお\nかきくけこ\"\nexit 99\n",
    "delta": "0:00:00.002687",
    "end": "2021-07-15 22:12:55.487638",
    "rc": 99,
    "start": "2021-07-15 22:12:55.484951"
}

STDOUT:

あいうえお
かきくけこ


MSG:

non-zero return code

PLAY RECAP **************************************************************************************************************
localhost                  : ok=1    changed=1    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0
```

正常終了時、異常終了時いずれも、結果詳細が整形されたJSONとして見やすく表示される。
さらに、STDOUT, STDERR, MSGなども\tや\nなどが解釈された上で正しく表示される。

#### ansible.cfgにverbosity = 1とstdout_callback = yamlを設定

なお、stdout_callback = yaml とすると表示がYAMLとなり、よりすっきりとした表示となる。
しかし、少なくともansible 2.9.10, Python 2.7.5, CentOS Linux 7 (Core)環境では複数日本語行の出力が確認できていない。
2022/04追記: MacOS 12.3 + ansible [core 2.12.3]では日本語複数行出力を確認。


```ini:ansible.cfg
[defaults]
verbosity = 1
stdout_callback = yaml
```

```
# ansible-playbook -i localhost, -c local site.yml
Using /root/roles/jp-stdout_callback/ansible.cfg as config file

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

TASK [日本語複数行出力] **************************************************************************************************
changed: [localhost] => changed=true
  ansible_facts:
    discovered_interpreter_python: /usr/bin/python
  cmd: |-
    echo "
    "
  delta: '0:00:00.002571'
  end: '2021-07-15 22:29:06.502209'
  rc: 0
  start: '2021-07-15 22:29:06.499638'
  stderr: ''
  stderr_lines: <omitted>
  stdout: |2+

  stdout_lines: <omitted>

TASK [日本語複数行出力後にエラー] ****************************************************************************************
fatal: [localhost]: FAILED! => changed=true
  cmd: |-
    echo "
    "
    exit 99
  delta: '0:00:00.002860'
  end: '2021-07-15 22:29:06.690787'
  msg: non-zero return code
  rc: 99
  start: '2021-07-15 22:29:06.687927'
  stderr: ''
  stderr_lines: <omitted>
  stdout: |2+

  stdout_lines: <omitted>

PLAY RECAP **************************************************************************************************************
localhost                  : ok=1    changed=1    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

```


#### 参照1 stdout_callback 

https://www.jeffgeerling.com/blog/2018/use-ansibles-yaml-callback-plugin-better-cli-experience

- https://www.jeffgeerling.com/blog/2018/use-ansibles-yaml-callback-plugin-better-cli-experience

こんなのがあったんですね。周知でしょうか？
もうデフォルトでいいのでは。



#### 参照2

**stdout_callback = yaml** 設定にてansible-playbook -vを実行時すると、taskのstdoutとして複数行の日本語が表示できない状況の様です。

https://teratail.com/questions/345583

この状況を回避？するには、ややフォーマットが異なりますが、**stdout_callback = debug** が使用可能でした。

-vなどは使っていなかったのですが、シェルモジュールのstdoutが、debug:タスクを使わずに、改行なども含めて正しく表示できるなんて、素晴らしい。


#### 追記

個人的には以下あたりが良さそう。


```ini:ansible.cfg
[defaults]
verbosity = 1
stdout_callback = debug
callback_whitelist = profile_tasks
```

callback_whitelist = profile_tasksはタスクの実行時刻、実行時間集計を表示してくれる。