Processing Command Output in Ansible
In Ansible, you often need to execute commands on remote hosts and process the output of those commands. This can be useful for a variety of tasks, such as gathering system information, checking service status, or even automating complex workflows. Ansible provides several ways to handle command output, and the approach you choose will depend on your specific requirements.
Capturing Command Output
The most common way to capture command output in Ansible is to use the command
or shell
modules. These modules allow you to execute commands on remote hosts and store the output in a variable. Here's an example:
- name: Execute a command
command: uptime
register: uptime_output
- name: Print the output
debug:
var: uptime_output.stdout
In this example, the uptime
command is executed on the remote host, and the output is stored in the uptime_output
variable. The stdout
field of the uptime_output
variable contains the actual command output.
Parsing Command Output
Once you have the command output stored in a variable, you can use various techniques to parse and extract the information you need. One common approach is to use the regex
or json_query
filters to extract specific data from the output.
For example, let's say you want to extract the system load average from the uptime
command output. You can use the regex
filter to do this:
- name: Execute the uptime command
command: uptime
register: uptime_output
- name: Extract the load average
set_fact:
load_average: "{{ uptime_output.stdout | regex_search('load average: (.*)') | first }}"
- name: Print the load average
debug:
var: load_average
In this example, the regex_search
filter is used to extract the load average value from the uptime
command output. The first
function is used to return the first match, as the regex_search
filter can return a list of matches.
Alternatively, you can use the json_query
filter to parse JSON-formatted command output:
- name: Execute a command that returns JSON
command: some_command_that_returns_json
register: json_output
- name: Extract a value from the JSON output
set_fact:
some_value: "{{ json_output.stdout | from_json | json_query('some.nested.value') }}"
- name: Print the extracted value
debug:
var: some_value
In this example, the from_json
filter is used to convert the JSON-formatted command output into a Python dictionary, and the json_query
filter is used to extract a specific value from the dictionary.
Handling Error Conditions
When executing commands in Ansible, it's important to handle error conditions properly. You can use the failed_when
or changed_when
options to define custom conditions for determining whether a task has failed or changed.
Here's an example of how to handle a command that may fail:
- name: Execute a command that may fail
command: some_command_that_may_fail
register: command_output
failed_when: command_output.rc != 0
- name: Print the output
debug:
var: command_output.stdout
In this example, the failed_when
option is used to mark the task as failed if the return code (rc
) of the command is not 0 (i.e., the command failed).
Handling Complex Command Outputs
Sometimes, the output of a command may be more complex than a simple string or JSON data. In such cases, you may need to use more advanced techniques to process the output.
One approach is to use the set_fact
module to create a custom data structure from the command output. For example, let's say you want to parse the output of the df
command to get a list of file system information:
- name: Execute the df command
command: df -h
register: df_output
- name: Parse the df output
set_fact:
file_systems: >
{{ df_output.stdout_lines[1:] | map('split', ' ') | map('list') | list }}
- name: Print the file system information
debug:
var: file_systems
In this example, the stdout_lines
field of the df_output
variable is used to get the output as a list of lines. The map
and list
filters are then used to split each line into a list of values and create a list of these lists, representing the file system information.
By using these techniques, you can effectively process and extract the information you need from command outputs in your Ansible playbooks.