The Essence of Ansible

The aim of this article is to give an overview of Ansible and attempt to explain its impressive adoption rate.

Ansible is a powerful IT configuration and automation framework with a low entry level. It provides a language to describe an arbitrary IT infrastructure as well as tools and an engine to read and put into effect the described configuration states. It is suitable for config management, app deployment, provisioning, continuous delivery, orchestration as well as security and compliance.

A Bit of History

Ansible was started as a project in February 2012 by Michael DeHaan. As he writes in a blog post he wanted to build a tool that a) he actually wanted to use, and b) that you could still remember how to use after six months of absence. Ansible Inc. was founded in 2013 as a commercial home for the tool and project providing support and consulting services. The IT automation software quickly gained popularity. In October 2015 Ansible was acquired by Red Hat.

Basics

Basic Ansible installation is as easy as installing a package on most modern Linux distributions. It is written in Python and therefore very portable. It comes as a set of command line executables as well as a wealth of modules (see modules list). When using SSH to connect to remote systems preparing for remote code execution is as easy as installing a public key on the remote site. If you can establish an ssh connection without password the system is ready for Ansible.

The executable “ansible” can be directly used to execute ad-hoc commands or one-off tasks. The remote systems are configured in a static configuration file on the controlling system or dynamically assembeled using an Ansible inventory plugin. The following example reports uptime of one or more webservers.

ansible webservers -a “uptime”

The response to above command is the standard output and might be similar to

webserver1.example.com | SUCCESS | rc=0 >
 14:00:07 up 9 days, 16:16, 2 users, load average: 0.10, 0.14, 
0.20

A wide range of actions can be called directly using modules. The following example updates the target system1 using the dnf module which corresponds to the standard dnf Linux utility.

ansible system1 -m dnf -a “name=* state=latest” -s

Any Ansible module code execution yields an easy to read response in JSON format. The output is conveniently colored to indicate success (green), problems and errors. This makes the response both humand and machine readable. Above command output could return something like

system1.example.com | SUCCESS => {
 “changed”: true,
 “results”: [
 “Installed: nss-tools-3.24.0-1.3.fc23.x86_64,
 “Removed: nss-tools-3.24.0-1.2.fc23.x86_64
 ]
 }

Most useful configurations consist of multiple tasks. In Ansible these are organized in playbooks containing Ansible markup using standard YAML syntax. Playbooks are files containing all work to be done on remote systems to achieve a desired state. The Ansible YAML markup allows for logic to be incorporated to model special cases, dependencies, conditional execution as well as exception handling. Playbooks can be executed using the command ansible-playbook.

A Playbook server_update.yml achieving a system update on a list of centos_servers (similar to the command line above) might look something like the following:

---
- hosts: centos_servers
 become: yes
 tasks:
 - name: Upgrades CentOS servers
 yum: name=* state=latest

The playbook can be executed with the command

ansible-playbook server_update.yml

Arguably the Ansible YAML syntax is easy to read and follow. The task syntax is somewhat self documenting, as the output will include the task names as defined in the playbook.

External programs and their resluts can easily be used in playbooks. See a test playbook:

---
- hosts: 127.0.0.1 # This could be set to any host group
 tasks:
 - name: Get public ip
 shell: wget http://ipecho.net/plain -O - -q
 register: public_ip

- debug: var=public_ip

The use of the jinja2 engine adds powerful templating capabilities for variable substitution inside playbooks as well as to dynamically create files to be transferred to remote hosts. Here’s a simple local template and sample playbook illustrate a transfer task (and to test it locally):

<html>
<head><title>Greetings</title></head>
<body>
<h1>{{ hello_string }}</h1>
{% if server_role is defined %}<p>This is a {{ server_role }}</p>
{% else %}<p>The server_role is unknown.</p>{% endif %}
</body>
</html>

---
- hosts: 127.0.0.1
 vars:
 hello_string: “Hello World”
 #server_role: “Web Server” # if commented out server_role is 
undefined
 tasks:
 - name: Install index page
 template: src=hello.html dest=/tmp/hello.html backup=yes

More complex Playbooks will most likely consist of multiple files organized in a logical tree structure. Ansible Roles can be created as self-contained structure of Ansible files. There is a community repository Ansible Galaxy where many Roles can be downloaded.

This is just a minimal introduction to wet the appetite for Ansible. Refer to the online documentation for more details.

Why Ansible

Ansible sports a number of characteristics that make it stand out amongst similar tools and which may explain why Ansible appeals to all kinds of professionals, from system administrators to managers.

Ansible is unique in that it does not need any daemons or other software on remote systems to manage them. Thus initial setup is minimal. This has some important consequences:

  • setup is simple
  • there is no need to maintain special software on remote systems.
  • There are no long-running processes running on remote systems. No resources are used unless tasks are active. No process dependencies exist, a task either succeeds of fails.
  • Since there are no agents there is no need for any monitoring and maintenance of such processes. This in turn increases stability and minimizes resources requirements.

A key concept of Ansible is that of remote execution. Any code needed for configuration, deployment etc is copied/pushed to remote systems, executed and discarded. This means:

  • the code executed only needs to be maintained on the controlling system
  • in a push oriented execution model remote systems do not talk back to the controlling node. This makes the whole system more robust and secure.
  • code on remote systems is executed as any user with the privileges to run the code. Thus code does not necessarily have to run with administrative privileges. If it does privilege escalation is done through standard mechanisms on the target system (eg. sudo).

Ansible is language agnostic. The tool itself as well as the standard modules are written in Python and therefore Python is a requirement on the controlling system. However, modules and therefore the code executed on the remote systems may be written in any language as long as it can return JSON or a key-value-pairs-per-line result. Developers can stay with their preferred language.

The Ansible markup language is easy to read yet powerful enough to allow for logic and error handling. Playbooks allow for structured organization of complex setups and are both human and machine readable.

Instead of re-implementing components such as secure communication protocols, Ansible leverages best of breed standard software wherever possible. For example looking at the communication layer Ansible comes with several well known mechanisms included. Connections to remote Linux/Unix hosts are made using SSH (OpenSSH or paramiko) management of Windows hosts uses WinRM and PowerShell. Other native possibilities include direct local execution and RabbitMQ as message queuing alternative or Docker container connectivity. Also, any REST API can be directly accessed.

  • network traffic can be secured with widely used and proven encryption libraries
  • using standard tools on the respective platforms makes it easy for system administrators to learn, minimal new skills are required.
  • there are no additional custom communication channels. Ansible is firewall friendly. Firewalls only have to be configured to allow traffic through standard ports (eg. ssh,https). In addition there are no sessions that need to be kept open over extended periods of time which could otherwise be a challenge in network firewall configurations.

Ansible is highly modular and extensible and comes with “batteries included”. Common functionality is implemented in modules. At the time of this writing more than 500 modules are included. The functionality can be extended by implementing custom modules. It is possible to add a custom connection method in the form of an Ansible connection plugin that might implement some proprietary transport protocol. An additional utility ansible-galaxy can directly make use of roles (portable, self contained playbooks) published in a community fed repository.

Commercial support is available through Red Hat. The company also offers a Web front end called Tower that helps with delegation of tasks and much more through a web application and API.

References

The main Ansible site is ansible.com. Reference documentation can be found through the site or here.

Some large infrastructure projects include Ansible projects for setup/configuration. Notably, openstack-ansible is an official OpenStack project for setting up and managing OpenStack cloud infrastructures.

Kommentare sind geschlossen.