Ansible: Tools and Features

Let's take a look at what Ansible is and its various tools and features.

What is Ansible?

Ansible was written by Michael DeHaan and developed by the Ansible Community, Ansible Inc., and Red Hat Inc.

According to the Red Hat whitepaper “Ansible in Depth”, the design goals for Ansible were:

  • Minimal in nature

  • Consistent

  • Secure

  • Highly reliable

  • Requiring minimal learning

Another distinguishing feature of Ansible is that it is agentless. SSH is used to connect Ansible to network devices. Configuration on the devices is only required for standard CLI access, and possibly a service account when using RSA or other forms of AAA authentication on the network. Aside from Ansible needing to log in to the device, there are no other requirements for the network. Ansible is also cross-platform across Linux, Windows, UNIX, F5 (BIG-IP), and Cisco network device OS (IOS, NX-OS).

Ansible by Red Hat is the open-source version, and Red Hat Ansible Engine is the commercially available version.

Ansible is an automation engine that runs playbooks written in YAML format. Tasks are executed serially and offer full orchestration control within a playbook.


Think of Ansible more as an automation framework rather than a programming language.

Ansible is not C++, or Java for networks. Rather it is a framework of tools made up of the following:

  • Inventory:

    • Static hosts.ini file

    • Possibly dynamic using API calls to NMS, IPAM, or inventory system already maintained with a list of network devices

  • Variables:

    • group_vars

    • host_vars

    • YAML format

    • Data models for network devices as a group and as individual devices

  • Playbooks:

    • YAML file format

    • Serial execution of tasks

    • Call Ansible modules

  • Templates:

    • Jinja2 file format

    • Dynamic calls to the variables at playbook run time

    • Mix of static text, simple logic (if, else, for), and variables

  • Plug-ins:

    • Python format

    • Extend base capabilities of core Ansible engine

    • Custom written

  • Modules:

    • Python and PowerShell format

    • Vendor-specific modules for communicating with devices


Python is a powerful, easy to learn, and open-source programming language that is the foundation for Ansible. Created by Guido van Rossum and released in 1991 Python has a design philosophy of readability.

The Ansible repository is available at GitHub, and it is possible to contribute to the community project. It is not necessary to understand the Python code Ansible is written in. However, understanding Python well makes it possible to write Ansible plug-ins using Python or contribute code to the Ansible project.


YAML Ain’t Markup Language (YAML) is a human-readable data serialization language commonly used for configuration files. YAML was created by Clark Evans, who designed it together with Ingy döt Net and Oren Ben-Kiki in 2001.

Most Ansible files, including group and host variables, tasks, and playbooks, are written in YAML format.


Jinja2, created by Armin Ronacher in 2008, is a full-featured templating engine for Python. Ansible templates are written in Jinja2 syntax. Templates are made up of a combination of static text, dynamic variables, and programmatic logic.


Ansible playbooks are written in YAML. Playbooks are executed against devices in the inventory file. For full configuration management, group variables, host variables, templates, and tasks need to be developed in addition to the inventory file. To run an Ansible playbook, execute the following command in the Linux host:

ansible-playbook <filename.yml>


Idempotency is a key feature of Ansible. To be idempotent means that the same task can be executed a single or multiple (infinite) times, and the results will always be the same. To say the network is idempotent means the source of truth- including the results from the Ansible playbook- and the running-configuration of a device, will match when compared.

Once idempotent, Ansible playbooks show the results of the playbook in green text. This indicates that no changes will be made because the two configurations are identical. If the configurations are not idempotent, the Ansible playbook will show a change in yellow text, reporting that a change will be made by the playbook.

By reaching full coverage of the network configurations and transforming the configurations to code, the master branch becomes a full representation of the network. All future changes become extremely easy to validate using the branching strategy of a working branch per change. These working branches can be executed in check mode.

Check Mode

Ansible playbooks have a check mode where playbooks can be tested without executing any changes. The combination of idempotency and check mode is very powerful. It can do the following:

  • Make code change

  • Run code in check mode with verbosity enabled

  • Confirm exact change reflected in the output of check mode

  • Run code in execute mode

  • Re-run the Ansible play in check mode to confirm play results are in green text indicating no changes will be made and that the automated configuration matches the running-configuration

Automating a mistake can lead to a faster impact, on a larger scale, than a mistake made manually at the CLI (a single device). For something as potentially dangerous as network automation in such a risk-averse field, check mode offers the ability to perform a dry run of a playbook without making any modifications to the network.

Check mode, on its own, will show the hosts in green text indicating no changes would have been made by the Ansible playbook if it was executed. Should changes be found, the hosts with the changes will be shown in yellow text instead of green.

This indicates that Ansible, in execute mode, would have pushed changes to the device. It also indicates the playbook is not idempotent. Results can be documented and included as artifacts in the change management approval process.

Stress is reduced and reassurance is offered, which further eases the transition to network automation. For all changes that cannot be performed in a lab environment, or for large disruptive changes touching many devices, check mode can be used to show the exact commands the playbook will execute serially, device-by-device.

ansible-playbook <playbook.yml> --check


Differentials (-- diff) are another option for Ansible playbooks. Diff is often used in conjunction with check mode. If the Ansible module supports diff, playbooks can be executed with the option set to compare the automated configuration against the device’s configuration. This is useful for before- and after- comparisons, or for fully understanding the changes the playbook would’ve made if run in execute mode.

ansible-playbook <playbook.yml> --diff

When combined with check mode and verbosity:

ansible-playbook <playbook.yml --check --diff -v

A detailed guide on “Check Mode (“Dry Run”)”.


Various levels of verbosity can be set when running the playbooks to provide more details in the output from the playbook. When combined with check mode, for example, adding one level of verbosity will show potential changes in yellow text, and also output the exact text of the configurations that would change.

Deeper levels of verbosity exist, and provide even more granular output. This is useful for troubleshooting playbooks.


Tags can be added to tasks within a playbook. They can help organize, group, or classify tasks, and are very useful for larger playbooks. Tagged tasks can be run inside a larger playbook. Conversely, it is possible to run all tasks except the tagged tasks. Tags are also a way to provide metadata and organizational structure to tasks.

A detailed guide to Ansible tags.

A guide to Ansible playbooks.

Get hands-on with 1200+ tech skills courses.