【Ansible×NW自動化】type_debugを使ってregisterのデータ型を確認する

# はじめに
<バージョン>
ansible 2.9.1

Ansibleにおいて、taskの結果をregisterに格納するのはよく行うと思います。
使用するモジュールなどによっては、registerの中身が複雑になり、初心者の方からすると
欲しい結果を取得するのが難しくなります。
そこで、今回は
 __「type_debugを使ってregisterの中身のデータ型を確認する習慣をつけましょう」__というお話

# 参考例1：現在時刻を取得する

__taskの内容__
（1）現在時刻を取得して、registerでdateに格納
（2）dateの中身を確認
（3）dateのデータ型を確認
（4）date.stdoutのデータ型を確認

```yaml:register_test1.yml
---
- name: debug TEST
  hosts: localhost
  gather_facts: no
  vars:
    ansible_python_interpreter: /usr/bin/python3
  tasks:
    - name: get date
      local_action: 'shell date +%Y_%m_%d_%H_%M_%S'
      register: date
      changed_when: false

    - name: debug all
      debug:
        msg: '{{ date }}'

    - name: check type - date
      debug:
        msg: '{{ date | type_debug }}'

    - name: check type - date_stdout
      debug:
        msg: '{{ date.stdout | type_debug }}'
```

# 出力結果1
出力結果から、データ型は以下のようになっていることがわかりました。
date：辞書
date.stdout：文字列

```text:出力1
PLAY [debug TEST] ***************************************************************************************************************************************************************************

TASK [get date] *****************************************************************************************************************************************************************************
ok: [localhost -> localhost]

TASK [debug all] ****************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": {
        "changed": false,
        "cmd": "date +%Y_%m_%d_%H_%M_%S",
        "delta": "0:00:00.004972",
        "end": "2020-01-10 10:59:26.412078",
        "failed": false,
        "rc": 0,
        "start": "2020-01-10 10:59:26.407106",
        "stderr": "",
        "stderr_lines": [],
        "stdout": "2020_01_10_10_59_26",    ←ココ
        "stdout_lines": [
            "2020_01_10_10_59_26"
        ]
    }
}

TASK [check type - date] ********************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "dict"
}

TASK [check type - date_stdout] *************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "AnsibleUnsafeText"
}

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

# 参考例2：junos機器からshowコマンドの結果を取得する
with_itemsで複数のshowコマンドの結果をjunos_resultsに格納します。
loop_controlは画面の出力がきれいになるだけなので、わからない方は無視してOKです。

__taskの内容__
（1）showコマンドの結果を取得して、registerでjunos_resultsに格納
（2）junos_resultsの中身を確認
（3）junos_results.resultsでループをまわし、stdoutのデータ型を確認
（4）junos_results.resultsでループをまわし、stdout[0]のデータ型を確認
（5）junos_results.resultsでループをまわし、stdout[0]の結果を出力
※なぜ、stdout[0]が出てくるかは、出力結果を見ればわかります
__ポイント__
・with_itemsの結果をregisterに格納すると、各ループの結果は __resister変数.results__ の中に格納されます

```yaml:register_test2.yml
---
- name: register TEST
  hosts: junos
  gather_facts: no
  vars:
    ansible_python_interpreter: /usr/bin/python3
    show_commands:
      - show system uptime
      - show system users
  tasks:
    - name: junos show command
      junos_command:
        commands: "{{ item }}"
      register: junos_results
      with_items: "{{ show_commands }}"

    - name: debug all
      debug:
        msg: "{{ junos_results }}"

    - name: debug command1 - type_debug
      debug:
        msg: "{{ item.stdout | type_debug }}"
      with_items: "{{ junos_results.results }}"
      loop_control:
        label: "{{ item.item }}"

    - name: debug command2 - type_debug
      debug:
        msg: "{{ item.stdout[0] | type_debug }}"
      with_items: "{{ junos_results.results }}"
      loop_control:
        label: "{{ item.item }}"

    - name: debug command
      debug:
        msg: "{{ item.stdout[0] }}"
      with_items: "{{ junos_results.results }}"
      loop_control:
        label: "{{ item.item }}"
```

# 出力結果2
出力結果から、データ型は以下のようになっていることがわかりました。
stdout：リスト
stdout[0]：文字列

参考例1では、stdoutは文字列だったのですが、今回はリストになっています。
データ型がわからないと、register結果の抽出に苦労するので注意しましょう。

```text:出力2
PLAY [register TEST] ************************************************************************************************************************************************************************

TASK [junos show command] *******************************************************************************************************************************************************************
ok: [junos_router_1] => (item=show system uptime)
ok: [junos_router_1] => (item=show system users)

TASK [debug all] ****************************************************************************************************************************************************************************
ok: [junos_router_1] => {
    "msg": {
        "changed": false,
        "msg": "All items completed",
        "results": [
            {
                "ansible_loop_var": "item",
                "changed": false,
                "failed": false,
                "invocation": {
                    "module_args": {
                        "commands": [
                            "show system uptime"
                        ],
                        "display": null,
                        "host": null,
                        "interval": 1,
                        "match": "all",
                        "password": null,
                        "port": null,
                        "provider": null,
                        "retries": 10,
                        "rpcs": null,
                        "ssh_keyfile": null,
                        "timeout": null,
                        "transport": null,
                        "username": null,
                        "wait_for": null
                    }
                },
                "item": "show system uptime",
                "stdout": [
                    "Current time: 2020-01-10 11:17:02 UTC\nTime Source:  LOCAL CLOCK \nSystem booted: 2020-01-09 19:59:07 UTC (15:17:55 ago)\nProtocols started: 2020-01-09 20:13:26 UTC (15:03:36 ago)\nLast configured: 2020-01-06 04:39:44 UTC (4d 06:37 ago) by jnpr\n11:17AM  up 15:18, 0 users, load averages: 0.37, 0.31, 0.32" 
                ],
      ココ→     "stdout_lines": [
                    [
                        "Current time: 2020-01-10 11:17:02 UTC",
                        "Time Source:  LOCAL CLOCK ",
                        "System booted: 2020-01-09 19:59:07 UTC (15:17:55 ago)",
                        "Protocols started: 2020-01-09 20:13:26 UTC (15:03:36 ago)",
                        "Last configured: 2020-01-06 04:39:44 UTC (4d 06:37 ago) by jnpr",
                        "11:17AM  up 15:18, 0 users, load averages: 0.37, 0.31, 0.32"
                    ]
                ]
            },
            {
                "ansible_loop_var": "item",
                "changed": false,
                "failed": false,
                "invocation": {
                    "module_args": {
                        "commands": [
                            "show system users"
                        ],
                        "display": null,
                        "host": null,
                        "interval": 1,
                        "match": "all",
                        "password": null,
                        "port": null,
                        "provider": null,
                        "retries": 10,
                        "rpcs": null,
                        "ssh_keyfile": null,
                        "timeout": null,
                        "transport": null,
                        "username": null,
                        "wait_for": null
                    }
                },
                "item": "show system users",
                "stdout": [
                    "11:17AM  up 15:18, 0 users, load averages: 0.42, 0.32, 0.32"
                ],
      ココ→     "stdout_lines": [
                    [
                        "11:17AM  up 15:18, 0 users, load averages: 0.42, 0.32, 0.32"
                    ]
                ]
            }
        ]
    }
}

TASK [debug command1 - type_debug] **********************************************************************************************************************************************************
ok: [junos_router_1] => (item=show system uptime) => {
    "msg": "list"
}
ok: [junos_router_1] => (item=show system users) => {
    "msg": "list"
}

TASK [debug command2 - type_debug] **********************************************************************************************************************************************************
ok: [junos_router_1] => (item=show system uptime) => {
    "msg": "AnsibleUnsafeText"
}
ok: [junos_router_1] => (item=show system users) => {
    "msg": "AnsibleUnsafeText"
}

TASK [debug command] ************************************************************************************************************************************************************************
ok: [junos_router_1] => (item=show system uptime) => {
    "msg": "Current time: 2020-01-10 11:17:02 UTC\nTime Source:  LOCAL CLOCK \nSystem booted: 2020-01-09 19:59:07 UTC (15:17:55 ago)\nProtocols started: 2020-01-09 20:13:26 UTC (15:03:36 ago)\nLast configured: 2020-01-06 04:39:44 UTC (4d 06:37 ago) by jnpr\n11:17AM  up 15:18, 0 users, load averages: 0.37, 0.31, 0.32"
}
ok: [junos_router_1] => (item=show system users) => {
    "msg": "11:17AM  up 15:18, 0 users, load averages: 0.42, 0.32, 0.32"
}

PLAY RECAP **********************************************************************************************************************************************************************************
junos_router_1             : ok=5    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
```

# まとめ
・registerの中身は、使用するモジュールや取得方法(with_itemsなど)によって異なる
　→ debugで中身を確認したり、type_debugでデータ型を確認することが大事！！！！