Running Ansible scripts¶
Ansible is a free software platform used for configuring and managing computers. It is written in Python and allows users to manage nodes (computers) over SSH.
Configuration files are written in YAML, a simple, human-readable, data serialization format.
Installing Ansible¶
Before you install Ansible make sure you have Python 2.6 or Python 2.7 on the controlling machine, you will also need an SSH client. Most Linux distributions come with an SSH client preinstalled.
If you encounter any problems during the installation, refer to the official documentation.
Windows¶
Windows is not supported as a controlling machine.
Running Ansible¶
To test your Ansible installation, run the following command
Note
you need a running SSH server on your machine for this to work:
ansible localhost -m ping
You should get the following output:
localhost | success >> {
"changed": false,
"ping": "pong"
}
Ansible Hosts file¶
Ansible keeps information about the managed nodes in the inventory or hosts file. Edit or create the hosts file:
vim /etc/ansible/hosts
This file contains a list of nodes for Ansible to manage. Nodes can be referred either with IP or host name. The syntax is the following:
192.168.1.50
aserver.example.org
bserver.example.org
You can also arrange hosts in groups:
mail.example.com
[webservers]
foo.example.com
bar.example.com
[dbservers]
one.example.com
two.example.com
three.example.com
Public Key access¶
To avoid having to type your user’s password to connect to the nodes over and over, using SSH keys is recommended.
To setup Public Key SSH access to the nodes. First create a key pair:
ssh-keygen
And follow the instructions on the screen. A new key pair will be generated and placed inside the .ssh folder in your user’s home directory.
All you need to do now is copy the public key (id_rsa.pub) into the authorized_keys file on the node you want to manage, inside the user’s home directory. For example if you want to be able to connect to training.geonode1.com as user geo edit the /home/geo/.ssh/authorized_keys file on the remote machine and add the content of your public key inside the file.
For more information on how to setup SSH keys in Ubuntu refer to this document.
Connect to managed nodes¶
Now that SSH access to the managed nodes is in place for all the nodes inside the Ansible inventory (hosts file), we can run our first command:
ansible all -m ping -u geo
Note
change geo with the username to use for SSH login
The output will be similar to this::
ansible all -m ping -u geo
84.33.2.70 | success >> {
"changed": false,
"ping": "pong"
}
We asked Ansible to connect to all the machine in our Inventory as user geo and run the module ping (modules are Ansible’s units of work, more on that later…). As you can see by the output, Ansible successfully connected to the remote machine and executed the module ping.
Ad hoc commands¶
An ad-hoc command is something that you might type in to do something really quick, but don’t want to save for later.
Later you are going to write so called Playbooks with the commands to run on the controlled node but for learning purposes ad-hoc commands can be used to do quick things.
One example of an ad-hoc command is the ping command we just ran. We typed in the command line and ran it interactively.
Another example:
ansible all -m shell -a "free" -u geo
84.33.2.70 | success | rc=0 >>
total used free shared buffers cached
Mem: 4049236 3915596 133640 0 650560 2487416
-/+ buffers/cache: 777620 3271616
Swap: 4194300 730268 3464032
In this example we ran the free command on the remote hosts to get memory usage stats. Note that we used the shell module (-m flag) with the command as the argument (-a flag).
File Transfer¶
Another use case for the Ansible command is to transfer files over SCP:
ansible 84.33.2.70 -m copy -a "src=/home/geo/test dest=~/" -u geo
84.33.2.70 | success >> {
"changed": true,
"dest": "/home/geo/test",
"gid": 1000,
"group": "geo",
"md5sum": "d41d8cd98f00b204e9800998ecf8427e",
"mode": "0664",
"owner": "geo",
"size": 0,
"src": "/home/geo/.ansible/tmp/ansible-tmp-1444051174.15-189094870931130/source",
"state": "file",
"uid": 1000
We used the ansible command to transfer the local file /home/geo/test to the remote node in user’s home directory (‘~/’).
Managing Packages¶
Another use case is installing or upgrading packages on the remote nodes. You can use the apt module to achieve this on Debian based systems or the yum module on Red Hat based systems:
ansible 84.33.2.70 -m apt -a "name=apache2 state=present"
For example the previous command will install the Apache web server on the remote system (if not present).
You can use the same module to make sure a package is at the latest version:
ansible 84.33.2.70 -m apt -a "name=apache2 state=latest"
Managing Services¶
Use the service module to ensure a given service is started on all web servers:
ansible webservers -m service -a "name=httpd state=started"
(where webserver is a group defined in Ansible Inventory)
Restart the service:
ansible webservers -m service -a "name=httpd state=restarted"
Or stop it:
ansible webservers -m service -a "name=httpd state=stopped"
For more information on ad-hoc command refer to the official documentation.
These were just a few of the modules available for Ansible. See the complete list available at the Ansible web site.
Ansible Playbooks¶
Playbooks are Ansible’s configuration, deployment and orchestration language.
Playbooks are a completely different way to use Ansible than in ad-hoc task execution mode, and are particularly powerful.
Playbooks can declare configurations, but they can also orchestrate steps of any manual ordered process.
While you might run the main /usr/bin/ansible program for ad-hoc tasks, playbooks are more likely to be kept in source control and used to push out your configuration or assure the configurations of your remote systems are in spec.
Playbooks language example¶
Playbooks are expressed in YAML format
Here is an example of a Playbook:
---
- hosts: webservers
vars:
http_port: 80
max_clients: 200
remote_user: root
tasks:
- name: ensure apache is at the latest version
yum: pkg=httpd state=latest
- name: write the apache config file
template: src=/srv/httpd.j2 dest=/etc/httpd.conf
notify:
- restart apache
- name: ensure apache is running (and enable it at boot)
service: name=httpd state=started enabled=yes
handlers:
- name: restart apache
service: name=httpd state=restarted
Every Playbook begins with three dashes at the very top of the file to indicate that this is a YAML file.
This example Playbook contains only one Play. The play is composed of three parts:
- hosts
- tasks
- handlers
The hosts part specifies to which hosts in the Inventory this playbook applies and how to connect to them.
The tasks part describes the desired state or actions to perform on the hosts.
The handlers part describes the handlers for this playbook (more on handlers later).
In the example above there are three tasks. Each task has a name, a module and zero or more arguments for the module.
The first task specifies that we want the latest version of Apache installed on the system. This is accomplished by the yum module.
The second task specifies a configuration file for Apache using a template. Template files are written in Jinja2 template language.
The third task make sure the Apache web server is running using the service module.
When you run a Playbook using the ansible-playbook command, Ansible will connect to the hosts specified in the hosts section and run the tasks one by one, in order.
One or more tasks may have a notify section (just like the second task in our example). The notify actions are triggered at the end of each block of tasks in a playbook, and will only be triggered once even if notified by multiple different tasks. When triggered, the corresponding handler will be executed. In the example above the handler will restart Apache because we changed a config file.
Run a Playbook¶
Now that we have created a sample Playbook, save it on the file system and execute it:
ansible-playbook test.yml -u geo
PLAY [84.33.2.70] *************************************************************
GATHERING FACTS ***************************************************************
ok: [84.33.2.70]
TASK: [test] ******************************************************************
ok: [84.33.2.70]
PLAY RECAP ********************************************************************
84.33.2.70 : ok=2 changed=0 unreachable=0 failed=0
This concludes our brief tutorial on Ansible. For a more thorough introduction refer the official documentation.
Also, take a look at the Ansible examples repository or a set of Playbooks showing common techniques.