A few years ago, Ansible introduced a very useful feature called --diff that has yet to be widely adopted in the network industry.
If you are already using Ansible you are probably familiar with the default output that will indicate, per task, if something has changed (or if it will be changed if you are running in --check mode). --diff and --check are two completely different features, both features can work independently and they work also well together.

Standard Ansible output Standard Ansible output

While it’s useful to understand if a change will be made, it’s even more important to be able to see exactly what has/will change. When running in --diff mode, Ansible will show you which changes have been completed.

Some modules are returning this kind of information by default but to access it, you need to enable the verbose (-vv) output which will print a lot of additional information on the screen. The --diff mode provide a better experience with colors etc ..

Here is an example of diff created by Ansible when generating a configuration file with the template module. The diff is showing only the lines that will change, with a few lines of context before and after. The line(s) that will be added to the file are in green and the line(s) that will be removed/updated are in Red. It’s important to highlight that even if there is a large amount of content, the diff will only show the relevant lines associated with the current changes.

Ansible diff on a configuration file Ansible Diff output

This function needs to be supported per module, but fortunately many built in modules are already configured for support, including: ios_config, eos_config, junos_config, template, blockinfile, lineinfile, replace, etc …

I haven’t found a way yet to determine if a module supports it from the documentation but you can test by:

  1. Giving it a try
  2. Looking at the source code

Ansible Module development : How to add diff support to your module

To support and generate a --diff, a module needs to return a dictionary called diff with either:

  1. Both versions of the content before and after the change (Ansible will generate the diff itself)
  2. A summary of the change as it will be generated by the module: prepared

It’s useful to have both options available because some system like Junos will be able to generate the diff directly and it will usually be easier to understand than doing a line by line diff.
For examle, Junos will always add the name of the section in the diff to help you understand where a change will happen where a generic line by line diff will usually only include few lines before and after the change to give some context but in some cases it might not be enough. In this case, you can provide the result directly using prepared instead of letting ansible generate the diff for you from the 2 versions of the content : before & after

{
  "diff": {
    "before": "<content before in string format>",
    "after": "<content after in string format>",
  }
}

or

{
  "diff": {
    "prepared": "<summary of the changes that has/will be applied>"
  }
}

If you want to know if the module is running in diff mode, you can check the variable module._diff.

When you are providing both before and after, Ansible will do a comparison of the two strings and return a diff similar to what git will generate.

How to use the diff beyond text content

The diff has been designed to work on text content (string) but other types of variables generate good results as well. The best way to support all types of variables is to convert any variables in a string formatted with YAML. This way, Ansible will still get 2 strings to compare–it’s just that these strings will be the representation of structured data.

Ansible diff on variablesfiguration Ansible Diff applied to a variables represented in YAML

To generate this output from your module, you can dynamically convert your variable into a Yaml formatted string before exiting

{
  "diff": {
    "before": yaml.dump(var_before)
    "after": yaml.dump(var_after)
  }
}

Continue the discussion at AnsibleFest 2019

The Network to Code team will be at Ansiblefest 2019 in Atlanta. Feel free to reach out about anything and everything Ansible-related or about network automation in general. We’re looking forward to meeting with everyone to discuss the latest Ansible news and trends.

-Damien