Skip to content

Work with JSON output of a Command#

Problem#

A complex service provides a command to get its status. The command has an option --json to switch to a machine readable format.

How can we check if the value of BackendState and run more tasks based on its value?

tailscale status --peers=false --json

{
  "Version": "1.74.1-tccd6bf2f4-g8fce4ce11",
  "TUN": true,
  "BackendState": "Running",
  "HaveNodeKey": true,
  "AuthURL": "",
  "TailscaleIPs": [
    "100.100.xx.xx"
  ],
  "Self": {
    "ID": "...",
    "...": "..."
}

Solution#

Install the Python dependency jmespath, then use the combination of the filters from_json and json_query get the value of a key.

- name: Tailscale status
  ansible.builtin.command: tailscale status --peers=false --json
  register: _tailscale__status
  changed_when: false

- name: Tailscale up
  ansible.builtin.command: >
    tailscale up
    --auth-key={{ tailscale__auth_token }}
    --advertise-routes={{ tailscale__subnets|join(',') }}
  when: _tailscale__status.stdout | ansible.builtin.from_json | community.general.json_query('BackendState') == 'NeedsLogin'

Explanation#

The output of the command is returned in json format but Ansible doesn't know that and returns it as String in output. That is why we need to turn it back to json using from_json first.

Also See#