Ansible is an open source software conceived to help sysadmins to manage the automation and a centralized orchestration of configuration procedures on Unix-like architectures. Its main characteristic is a mix of richness in features and an easy learning curve.
Ansible leverages two structured elements: node and control machines. As the name suggests, the latter are the computers that actually realize orchestration by means of commands for the underlying nodes via SSH and JSON. A very important point of strength of Ansible is being comprehensible without particular development skills (a prior knowledge of syntax and constructs is not required), tied with a sequential execution of control tasks. Its main uses are application deployment, distributed configuration management and work fluxes orchestration.
Ansible is agentless, that is, it doesn’t require a software agent (client, service or daemon) on target machines: it just requires an OpenSSH server and WinRM onboard (the latter for Windows machines only). This approach has several advantages: less efforts in terms of time and resources on the machines to manage (evident in the case of extended environments) and an improved level of security as for software maintenance on endpoints in the long run is concerned being the most important ones.
Configuration specifications are written in YAML documents (YAML is an intuitive language, indentation-based, for data serialization) that are called Playbooks. Configuration specs operate by means of Tasks, or event managers, which will be covered later. Playbooks, if carefully compiled, can contain complex configurations that can manage critical and even unexpected situations on nodes.
As stated before, Ansible is open source and comes in two different implementations: Ansible Core and Ansible Tower. The former is free, while the latter -owned by Red Hat- has a license price (5000 to 14000 EUR per year) and offers a number of advanced features for nodes control and management, automation with RESTful APIs and dedicated support.
Use cases and key concepts
There are some typical use cases for Ansible: Configuration Management -ie the setup and configuration of remote server with the installation of packages, updates and service. Another situation is Security Management -ie the maintenance of machines up to date and the fixing of any vulnerabilities in a centralized and quick way, and the Provisioning and Orchestration of IT infrastructure (addition and initialization of new instances). Continuous Delivery, a typical paradigma of DevOps, can be managed with Ansible too.
Before installing and starting to use it, let’s define a couple of key concepts of Ansible:
- INVENTORY: a collection of nodes and groups Ansible can connect to and manage.
- TASK: an instruction that Ansible executes, in order, on target nodes.
- HANDLER: an instruction that is executed if a precise action triggers it.
- PLAY and PLAYBOOK: a play is a set of ordered tasks to run on nodes of the inventory. A playbook is a file with one or more plays.
- ROLE: a series of contents tightly related that help to manage and maintain a number of playbooks.
Specifically, the inventory is a set of hosts with specific characteristics and group of nodes that can be connected and managed together, singularly or per-group.
Installation and functioning
Installing Ansible is easy and depends on the operating system where it is to be installed, the Ansible Management Node, which is the one where the user creates playbooks. The following picture illustrates the commands require to install it from command line on different Linux flavours.
Playbooks
Playbooks and modules are run on nodes in the Inventory, which are the one available for the execution of deployment; such hosts are called target nodes. Modules are portions of code transferred to nodes to be run and satisfy the declarations of a certain task.
They can be run via CLI or automated in a task of a playbook.
The website www.ansible.com offers a complete documentation of modules, grouped per category: Windows, network, Web, system, commands, utilities, etc.. .
Documentation is fundamental as it describes parameters and the require configuration to assure a proper functioning.
Standard modules don’t cover all possible combinations, but this limit can be easily overcome by creating new ones. To do that you should use modules in the Command category which, as the name implies, run commands. There are four Command modules: Command, Shell, Script and Raw.
Command
A command receives a command and runs it on the target host, Shell runs a command from a shell like /bin or /sh in order to use pipes. Script runs a local script on a remote node before transferring it on the node itself and lastly, Raw runs a command without using Ansible modules: it works externally.
Ansible provides ad-hoc commands that can be run freely without saving them. Such commands can be run with no restrictions, so they don’t require a dedicated playbook.
Here’s some examples:
$ ansible all –m ping
This command performs a ping on all nodes of the Inventory, and alive nodes will send a reply.
$ ansible all –m command -a “uptime”
This command runs the Command module with the “uptime” attribute on nodes, so they reply with information on their uptimes.
Facts
Facts, also known as Discovered Facts, are set of information provided by nodes that can be stored as variables for later use in playbooks.
They’re quite useful in some case, for instance when we want to know the attributes of the systems we’re working on. Here’s an example:
$ ansible localhost -m setup
localhost | success >> {
"ansible_facts": {
"ansible_default_ipv4" : {
"address": "192.168.1.37",
"alias": "wlan0",
"gateway": "192.168.1.1",
"interface": "wlan0",
"macaddress": "c4:85:08:3b:a9:16",
"mtu": "1500",
"netmask": "255.255.255.0",
"network": "192.168.1.0",
"type": "ether"
},
},
}
To perform this operation, a specific setup module (-m setup) retrieves information on target hosts and creates a recap in a way that can be used in plabooks. Facts aren’t the only type of variable; generica variables are called, indeed, Variables, and can be created from commands run via CLI, Play and Tasks, external files, Facts, Roles and the whole Inventory.
Tasks
Another key concept are Tasks, that is, the instructions that Ansible run sequentially on target nodes. Shortly, a task is the application of a Module aimed to perform a certain operation.
Each playbook contains a list of tasks that are run on every target node. The most used modules include:
- file: creates a directory if it doesn’t exist.
- yum: installs a package.
- service: runs the service passed as parameter.
- template: creates a configuration file from a certain template.
- get_url: retrieve an archive file from the URL passed as parameter.
- git: clone a repository from source code.
An example of task in a playbook is the following one:
task:
-name: httpd package is present
yum:
name: httpd
state: latest
-name: latest index.html is present
copy:
src: files/index.html
dest: /var/www/html/
-name: restart httpd
service:
name: httpd
state: restarted
In details, the first task installs the package called httpd (Apache Web Server) which is already present in the system and uses the latest state control parameter to check if it has to be overwritten if the latest version is not installed. Each task has a name that is not mandatory, but it’s recommended in order not to create confusion and for quick identification.
The second task downloads a file, whose name and path follow the src part, and writes it, with the copy module, on servers whose path is specified after the dest: specification. The last task starts Apache Web Server to apply the modifications hereby done.
Handler tasks
Let’s talk about handlers now. Handlers are sets of instructions that are executed as the consequence of a certain action. Handlers are special tasks run at the end of a play or when a change is detected and notified by another task: for instance if a task updates a database of a configuration file, it also notifies it to the related handler so that it can restart the service, in order to apply the change.
task:
-name: httpd package is present
yum:
name: httpd
state: latest
notify: restart httpd
-name: latest index.html is present
copy:
src: files/index.html
dest: /var/www/html/
handlers:
-name: restart httpd
service:
name: httpd
state: restarted
The previous example shows the example task with the addition of the notify:restart https instruction which forwards to the restart http handler. Note that the handler is called only if the notify condition is actually verified.
In the next issue we will cover other aspects and terminology of Ansible like Templetes, conditional format of playbooks and some practical examples.