paul_venezia
Senior Contributing Editor

Review: Ansible orchestration is a veteran Unix admin’s dream

reviews
Oct 10, 201311 mins

Ansible and AnsibleWorks AWX bring simplicity and power to Linux and Unix server automation

Many server automation and orchestration solutions, like Puppet and Chef, rely on a mixture of solution-specific coding, Web UIs, and command-line tools to make the magic happen. Ansible is different. Although a Web UI is available, Ansible plays very well on the Unix admin’s home turf: general scripting and the command line.

Ansible is an extremely flexible open source toolkit that makes it very easy for Unix hands to get started with automated configuration management and orchestration. It uses a push method of configuring client systems, so everything stems from a master server. And to the powerful CLI, you can add a commercially licensed Web UI to provide for delegated administration and provisioning.

[ Review: Chef cooks up configuration management | Review: Puppet Enterprise 3.0 pulls more strings | Puppet or Chef: The configuration management dilemma | Subscribe to InfoWorld’s Data Center newsletter to stay on top of the latest developments. ]

Installing Ansible

Installing Ansible is quite simple. You can either clone the Git repository and start from there, or you can use package management tools on your *nix of choice to download and install the packages. This will ensure that you have the required packages and Python 2.6 executables, and within a few minutes, you will have an Ansible master server configured.

In general terms, you’ll deploy Ansible with a central server and with configured groups of clients to be managed, using hostnames in an Ansible hosts file. The configuration required on the managed hosts is minimal, requiring only a functional Python 2.4 or 2.6 build and configuration of SSH authorized_keys to allow for connections from the Ansible master server to each host.

There are many ways to go about this, as you can configure Ansible to connect to hosts as a certain user or as the user running the commands on the master server. You can go with root as the user, but many will prefer to connect using a normal user account and working with sudo on the target to run commands as root.

As an example, we might have a user named “ansible” on our master server; we would then add an “ansible” user to our managed hosts and give that user passwordless sudo capabilities. Alternatively, we could specify passwords for sudo on the hosts, or we could specify a different username to be utilized when connecting. The ultimate goal is to allow the Ansible control executable to be able to connect to each configured host via SSH and run commands. That’s all there is to Ansible master and client configuration.

How Ansible works

Once the basic setup of our master and managed hosts has been done, we can start looking at what Ansible can do. Here’s a simple example:

[ansible@ansible1: ~]$ ansible all -m ping -u ansible -sudo ansiblecentos.iwlabs.net | success >> {     "changed": false,     "ping": "pong"}

ansibleubuntu.iwlabs.net | success >> {     "changed": false,     "ping": "pong" }

Here we ran a simple ping command to make sure that our managed hosts are configured and answering. The result is that both targeted hosts are ready and waiting.

InfoWorld Scorecard
Scalability (20.0%)
Value (10.0%)
Performance (10.0%)
Interoperability (20.0%)
Management (20.0%)
Availability (20.0%)
Overall Score (100%)
AnsibleWorks Ansible 1.3 8.0 9.0 9.0 7.0 8.0 9.0 8.2

Now, we can run a few other commands to investigate further:

[ansible@ansible1: ~]$ ansible all -m copy -a "src=/etc/myconf.conf dest=/etc/myconf.conf" -u ansible -sudo

ansiblecentos.iwlabs.net | success >> {

    "changed": true,     "dest": "/etc/myconf.conf",     "gid": 500,     "group": "ansible",     "md5sum": "e47397c0881a57e89fcf5710fb98e566",     "mode": "0664",     "owner": "ansible",     "size": 200,     "src": "/home/ansible/.ansible/tmp/ansible-1379430225.64-138485144147818/source",     "state": "file",     "uid": 500 }

ansibleubuntu.iwlabs.net | success >> {     "changed": true,     "gid": 1000,     "group": "ansible",     "mode": "0664",     "owner": "ansible",     "path": "/etc/myconf.conf",     "size": 200,     "state": "file",     "uid": 1000 }

As you can see, these commands will cause the file /etc/myconf.conf to be copied to our two managed hosts. We will also get a JSON object returned with data on the copy, file ownership, and so forth. We can specify alternate ownership, permissions, and other variables on the command line as well.

We can also do things like make sure that a service is set to start at boot:

[ansible@ansible1: ~]$ ansible webservers -m service -a "name=httpd state=running" u ansible -sudo

Or we can reboot those hosts:

[ansible@ansible1: ~]$ ansible webservers -m command -a "/sbin/reboot -t now"

Or we can pull an inventory of each client:

[ansible@ansible1: ~]$ ansible  all -m setup  -u ansible --sudo

That last command will output JSON objects describing each client, including total RAM, used RAM, CPU, network, and disk information, the OS version, kernel version, and so forth.

As you can see, Ansible provides a way to execute commands, gather data, and copy files to the targets, based on command-line parameters.

This functionality, by itself, could be done with only SSH and some scripting. Executing commands via SSH on remote hosts is as old as the hills, after all. What Ansible adds is the ability to make all that happen with a shorthand parameter set, along with grouping, inventory, and other higher-level management of the hosts. Each Ansible command-line function offers many options, such as the ability to reference multiple groups or to run the commands on a subset, such as only the first 50 servers in a group.

These capabilities will be instantly usable by Unix admins, and working with Ansible’s tools to script up quick and simple automation and orchestration tasks is ultimately very easy. Further, we can also build Playbooks to collect sets of commands and tasks for simple management.

Ansible Playbooks Playbooks are constructed using YAML syntax, so they are generally easily readable and configurable. For instance, this simple Playbook will make sure that NTPD is running on all hosts, using the “ansible” user and sudo to connect:

--- - hosts: all   remote_user: ansible   tasks:     - service: name=ntpd state=started       sudo: yes

We can also use Playbooks to do file copies. This is the Playbook version of the file copy noted above, but specifying the owner and permissions of the file on the client:

---

- hosts: all

  remote_user: ansible

  tasks:

    - name: Copy file to client

      copy: src=/etc/myconf.conf dest=/etc/myconf.conf

            owner=root group=root mode=0644

We can also use variables in Playbooks: 

---

- hosts: webservers   remote_user: root   vars:      ntp_service: 'ntpd'   tasks:     - service: name={{ ntp_service }} state=started       sudo: yes

Beyond these examples is the use of templates. We can build templates that reference variables, then call those templates from within Playbooks to construct files as we require. We might create a template file for an Apache configuration and place that configuration on our clients using variables specified in the Playbook:

template: src=/srv/templates/apache.conf dest=/etc/httpd/conf.d/{{ vhost }}.conf

Of course, we may need to restart services afterward, and we can do that with the notify and handler functions:

notify:

restart apache handlers:     - name: restart apache       service: name=apache state=restarted

The combination of all of these commands in a Playbook would make sure the appropriate virtual host configuration file is in place on the client, then restart Apache afterward so that the configuration changes will be picked up.

As you might expect, we can include files in Playbooks. We could create a file with all of our necessary handlers, then include just that file in new Playbooks. Thus, we could keep all those handlers configured in one place and still make them available throughout all Playbooks.

Further, you can configure roles that allow for collections of handlers, tasks, and variables to be included in Playbooks that reference those roles. For instance, you might have a set of handlers and tasks just for database servers, so you would set up a database role containing those files, then add the role to a Playbook to have all of those elements included in the Playbook. You can also configure dependencies that reference other roles as required.

Thus, constructing Playbooks is not only straightforward, but also offers significant extensibility and natural organization. In addition, Playbooks are very simple to run:

[ansible@ansible1: ~]$ ansible-playbook myplaybook.yml -f 10

This command will run the Playbook myplaybook.yml with a parallelization of 10, meaning that the server will connect and run myplaybook.yml on 10 clients at once.

While Ansible uses paramiko, a Python SSH2 implementation, or native SSH to communicate with clients, there can be a scalability issue when moving into large numbers of clients. To address this, Ansible 1.3 offers an accelerate mode that launches a daemon over SSH that provides AES-encrypted communication directly with the client. This feature can speed up client communications substantially when measured in large-scale implementations as compared to paramiko or native SSH.

Ansible modules Ansible includes a number of modules that allow for extended functionality, such as configuration and management of cloud services (say, Amazon EC2), as well as service-specific modules for popular database servers, file operations, and network devices. You can also create your own modules to handle site-specific requirements. Modules can be written in nearly any language, not just Python, so you could use Perl or Bash or C++ to create your modules.

Modules can be written to accept variables, and they are required to output JSON objects noting the status of the command along with any pertinent information that may be collected during runtime.

AnsibleWorks AWX A Web UI is available for Ansible in the form of AnsibleWorks AWX. This is a for-cost solution that offers a crisp and clean Web UI built around Ansible. However, the Web UI doesn’t tie into an existing Ansible configuration by default; if you have an extensive Ansible installation on a server, adding AWX on top of it isn’t going to immediately Web-ify that structure. You can use CLI tools to import existing Ansible inventories into AWX, then continually synchronize the two if you need to maintain CLI and AWX simultaneously.

Once you install and run AWX, you can configure users, teams, inventories, projects, and job templates based around your infrastructure. However, note that you’re adding these as new; they are not based on existing configuration files that may already include all of your hosts and configurations. AWX also provides a RESTful API, as well as integration with LDAP and Active Directory for authentication and authorization. This integration can be handy for mapping users and groups to organizations within the UI.

The AWX Web UI is clean and relatively intuitive, and it allows for fairly fast implementation. The UI is based strictly on Playbooks, so there are no command-line functions to leverage. You construct Playbooks via the CLI for your desired actions, then place them in specific directories on the server. You can then access them in the UI under Job Templates, then attach them to Inventories, and those jobs can be run.

The Web UI is functional, but it is neither as complete nor as useful as the command-line interface. You can’t schedule jobs through the Web UI, for example, whereas you can easily schedule jobs via cron on the command line. Playbooks can be run from either the Web UI or the CLI or both, so if you have a sizable CLI-based installation, your Playbooks will move over with little fuss. The rest of the structure will have to be duplicated via synchronization, however.

AnsibleWorks AWX also provides simple Web-based integration with various cloud services through various Ansible modules, so you can provide a Web UI for internal users and teams to provision public or private cloud services from a local management console, authenticated and authorized against your local LDAP or AD infrastructure. In this way, it can function as a self-service portal for internal customers.

Ansible works The long and the short of Ansible is that it’s extremely lithe and extremely simple to set up and get running. The Web UI is usable, but for more than general, prepackaged tasks, the CLI provides a much more malleable and productive solution.

There are no built-in provisions for high availability, but the simplicity of the solution makes it easy to use multiple systems to control clients. As long as the various “Playbooks” and configuration elements are present on multiple servers, high availability isn’t really an issue.

The lack of Windows support brings down our Interoperability score, but it should be noted that Ansible is really devoted to Linux and Unix administration.

Ansible’s design and implementation is right in the wheelhouse of veteran Unix admins. Ansible doesn’t do Windows, and it doesn’t offer many frills and baubles. But what it does provide is a fast and easy method to get Linux and Unix systems in line.

This article, “Review: Ansible orchestration is a veteran Unix admin’s dream,” was originally published at InfoWorld.com. Follow the latest developments in application development, cloud computing, and open source at InfoWorld.com. For the latest business technology news, follow InfoWorld.com on Twitter.