Ansible Tutorial
  • Share this blog:


Welcome to the Ansible Tutorials. The objective of these tutorials is to get an in-depth understanding of Ansible. In these tutorials, we will cover various Ansible functions with examples. The tutorial starts with an overview of Ansible, Installation of Ansible.

In addition to these tutorials, we will also cover common issues, Interview questions, and How To’s of Ansible.

Introduction to Anisible

Ansible is an IT automation tool. It can configure systems, deploy software, and orchestrate more advanced IT tasks such as continuous deployments or zero downtime rolling updates.

Ansible manages machines in an agentless manner. Because OpenSSH is one of the most peer-reviewed open source components, security exposure is greatly reduced. Ansible is decentralized–it relies on your existing OS credentials to control access to remote machines. If needed, Ansible can easily connect with Kerberos, LDAP, and other centralized authentication management systems.

Ansible is open source software (GPLv3) and is developed by a large group of industry experts from all over the world.

Ansible Architecture


Ansible runs on a central computer. Playbooks define configuration policy and orchestration workflows. Ansible then uses SSH to execute modules on remote machines without having to install any systems management software. Ansible comes with a large selection of modules for automating common tasks, and users can also write their own in their choice of favorite language. Inventory can be sourced from simple text files, the cloud, or configuration management databases (CMDBs). Results can be stored and processed into a variety of systems.

Configuration and Defaults

New in version 0.7+.

Ansible has an optional configuration file that can be used to tune settings and also eliminate the need to pass various command-line flags. Ansible will look for the config file in the following order, using the first config file it finds present

  • File specified by the ANSIBLE_CONFIG environment variable
  • ansible.cfg in the current working directory. (version 0.8 and up)
  • ~/.ansible.cfg
  • /etc/ansible/ansible.cfg

For those running from source, a sample configuration file lives in the examples/ directory. The RPM will install configuration into /etc/ansible/ansible.cfg automatically.

Installation of Ansible

Configuration management systems are designed to make controlling large numbers of servers easy for administrators and operations teams. They allow you to control many different systems in an automated way from one central location.

Install ansible on an RHEL/CentOS Linux based system

$ Sudo yum install ansible

Install ansible on a Debian/Ubuntu Linux based system

$ Sudo apt-get install software-properties-common $ sudo apt-add-repository PPA:ansible/ansible $ Sudo apt-get update $ Sudo apt-get install ansible

Install ansible using pip

A pip command is a tool for installing and managing Python packages, such as those found in the Python Package Index.

$ Sudo pip install ansible

the latest version of ansible using source code

$ cd ~ $ git clone git:// $ cd ./ansible $ source ./hacking/env-setup

When running ansible from a git checkout,  remember that you will need to set up your environment every time you want to use it, or you can add it to your bash RC file.

# ADD TO BASH RC $ echo "export ANSIBLE_HOSTS=~/ansible_hosts" >> ~/.bashrc $ echo "source ~/ansible/hacking/env-setup" >> ~/.bashrc

The host's file for ansible is basically a list of hosts that Ansible is able to perform work on. By default, Ansible looks for the host's file at /etc/ansible/hosts, but there are ways to override that which can be handy if you are working with multiple installs or have several different clients for whose datacenters you are responsible for.

$ ansible all -m shell -a "hostname" --ask-pass -i


The environment variable is $ANSIBLE_HOSTS, and can be set as follows:

$ export ANSIBLE_HOSTS=~/ansible_hosts

Once all requirements are installed and you have your host file setup you can give it a test run. For a quick test I put into the ansible hosts file as follow:

$ echo "" > ~/ansible_hosts

Now lets test with a quick ping:

$ ansible all -m ping

OR ask for the ssh password:

$ ansible all -m ping --ask-pass

it is highly recommended you set up keys for ansible to use but in the previous test we used --ask-pass, on some machines you will need to install sshpass or add a -c paramiko like so:

$ ansible all -m ping --ask-pass -c paramiko

Want to acquire industry skills and gain complete knowledge of Ansible? Enroll in Instructor-Led live Ansible Training to become Job Ready!

Setup SSH Keys

-c and --ask-pass options:
Generating public/private rsa key pair.
Enter file in which to save the key (/home/mike/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/mike/.ssh/id_rsa.
Your public key has been saved in /home/mike/.ssh/
The key fingerprint is:
The key's randomart image is:
+--[ RSA 2048]----+
|... . . |
|. . + . . |
|= . o o |
|.* . |
|. . . S |
| E.o |
|.. .. |
|o o+.. |
| +o+*o. |

$ ansible all -m copy -a "src=/home/mike/.ssh/ dest=/tmp/" --ask-pass -c paramiko

There are many ways to put this in place on the remote machine but since we are using ansible.


SSH password: | success >> {
    "changed": true,
    "dest": "/tmp/",
    "gid": 100,
    "group": "users",
    "md5sum": "bafd3fce6b8a33cf1de415af432774b4",
    "mode": "0644",
    "owner": "mike",
    "size": 410,
    "src": "/home/mike/.ansible/tmp/ansible-tmp-1407008170.46-208759459189201/source",
    "state": "file",
    "uid": 1000

Add the public key in remote server, enter:
$ ansible all -m shell -a "cat /tmp/ >> 
/root/.ssh/authorized_keys" --ask-pass -c paramiko


SSH password: | FAILED | rc=1 >> /bin/sh: /root/.ssh/authorized_keys: Permission denied

To run things as root, so let's add a -u option:

$ ansible all -m shell -a "cat /tmp/ >>

/root/.ssh/authorized_keys" --ask-pass -c paramiko -u root


SSH password: | success | rc=0 >>

File transfer using ansible

$ ansible all -m authorized_key -a "user=mike key='{{ lookup('file',

'/home/mike/.ssh/') }}'

path=/home/mike/.ssh/authorized_keys manage_dir=no" --ask-pass -c



SSH password: | success >> {
    "changed": true,
    "gid": 100,
    "group": "users",
    "key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCq+Z8/usprXk0aCAPyP0TGylm2MKbmEsHePUOd7p5DO1QQTHak+9gwdoJJavy0yoUdi+C+autKjvuuS+vGb8+I+8mFNu5CvKiZzIpMjZvrZMhHRdNud7GuEanusTEJfi1pUd3NA2iXhl4a6S9a/4G2mKyf7QQSzI4Z5ddudUXd9yHmo9Yt48/ASOJLHIcYfSsswOm8ux1UnyeHqgpdIVONVFsKKuSNSvZBVl3bXzhkhjxz8RMiBGIubJDBuKwZqNSJkOlPWYN76btxMCDVm07O7vNChpf0cmWEfM3pXKPBq/UBxyG2MgoCGkIRGOtJ8UjC/daadBUuxg92/u01VNEB",
    "key_options": null,
    "keyfile": "/home/mike/.ssh/authorized_keys",
    "manage_dir": false,
    "mode": "0600",
    "owner": "mike",
    "path": "/home/mike/.ssh/authorized_keys",
    "size": 410,
    "state": "file",
    "uid": 1000,
    "unique": false,
    "user": "mike"

The keys are in place lets try running an arbitrary command like hostname and hope we don’t get prompted for a password

$ ansible all -m shell -a "hostname" -u root

output: | success | rc=0 >>

Run commands as root and not be bothered by using a password we are in a good place to easily configure any and all hosts in the ansible hosts file. Let’s remove the key from /tmp:

$ ansible all -m file -a "dest=/tmp/ state=absent" -u root

output | success >> { "changed": true, "path": "/tmp/", "state": "absent" }

$ ansible all -m zypper -a "name=apache2 state=latest" -u root

output | success >> {

"changed": false,


"apache2", "state": "latest" }

This brings me to the next point, something that makes ansible very flexible and gives more power to playbooks, many may have noticed them zypper in the previous commands. Now unless you use OpenSuse or Suse enterprise you may not be familiar with zypper, it is basically the equivalent of yum in the suse world. In all of the examples above, I have only had one machine in my host's file, and while everything but the last command should work on any standard *nix systems with standard ssh configs, this leads to a problem.

$ cat ~/ansible_hosts



Create some groups of servers, and give them some meaningful tags. Then we create a playbook that will do different things for the different kinds of servers. You might notice the similarity between the yaml data structures and the command line instructions we ran earlier. Basically the -m is a module, and -a is for module args. In the YAML representation, you put the module then :, and finally the args.

- hosts: SUSEBased
  remote_user: root
    - zypper: name=apache2 state=latest
- hosts: RHELBased
  remote_user: root
    - yum: name=httpd state=latest

simple playbook, we can run it as follows:

$ ansible-playbook testPlaybook.yaml -f 10


PLAY [SUSEBased] **************************************************************
GATHERING FACTS ***************************************************************
ok: []
TASK: [zypper name=apache2 state=latest] ************************************** 
ok: []
PLAY [RHELBased] **************************************************************
GATHERING FACTS ***************************************************************
ok: []
ok: []
TASK: [yum name=httpd state=latest] ******************************************* 
changed: []
changed: []
PLAY RECAP ********************************************************************                 : ok=2    changed=1    unreachable=0    failed=0                 : ok=2    changed=1    unreachable=0    failed=0                  : ok=2    changed=0    unreachable=0    failed=0

The -f is what lets ansible run on multiple hosts in parallel. Instead of using all, or a name of a host group, on the command line you can put these passwords for the ask-pass prompt into the playbook. While we no longer need the –ask-pass since we have ssh keys setup, it comes in handy when setting up new machines, and even new machines can run from a playbook. To demonstrate this let's convert our earlier key example into a playbook:



- hosts: SUSEBased
  remote_user: mike
  sudo: yes
    - authorized_key: user=root key="{{ lookup('file', '/home/mike/.ssh/') }}" path=/root/.ssh/authorized_keys manage_dir=no
- hosts: RHELBased
  remote_user: mdonlon
  sudo: yes
    - authorized_key: user=root key="{{ lookup('file', '/home/mike/.ssh/') }}" path=/r

Machines need to change over time, you don’t need to re-write a playbook every time a machine changes, just update the pertinent bits and commit the changes. Another benefit of this ties into what I said earlier about being able to manage the entire infrastructure from multiple places. You can easily git clone your playbook a new machine and be completely set up to manage everything in a repetitive manner.

About Author
Author Bio

TekSlate is the best online training provider in delivering world-class IT skills to individuals and corporates from all parts of the globe. We are proven experts in accumulating every need of an IT skills upgrade aspirant and have delivered excellent services. We aim to bring you all the essentials to learn and master new technologies in the market with our articles, blogs, and videos. Build your career success with us, enhancing most in-demand skills in the market.

Stay Updated

Get stories of change makers and innovators from the startup ecosystem in your inbox