How to Install and Configure latest version of Ansible on Ubuntu Linux

I am a new Ubuntu Linux user. How do I install Ansible on a Ubuntu Linux 16.04/18.04/20.04 LTS or 20.10 desktop control machine?

Introduction: Ansible is a simple and easy to use IT automation tool. One can use Ansible to deploy applications and systems/VM/containers. Ansible configuration is written in plain English and works on the remote/local server using SSH. No agents needed on the remote server. In this guide, you will install latest version of Ansible on an Ubuntu Linux 16.04/18.04/20.04 LTS or 20.10 desktop system and learn some basics of how to use the software for automation purpose.
How To Install and Configure latest version of Ansible on Ubuntu

Tutorial details
Difficulty level Easy
Root privileges Yes
Requirements Ubuntu
Est. reading time 15m

Please note that you need to remove older version using sudo apt remove ansible && sudo apt --purge autoremove command supplied by the official Ubuntu repo.

How to Install and Configure latest version of Ansible on Ubuntu Linux

You must configure the PPA on your system to install the latest version of ansible. To manage the repositories that you install software from various PPA (Personal Package Archives). It allow you to upload Ubuntu source packages to be built and published as an apt repository by Launchpad. Type the following apt-get command or apt command:
$ sudo apt update
$ sudo apt upgrade
$ sudo apt install software-properties-common

Next add ppa:ansible/ansible to your system’s Software Source:
$ sudo apt-add-repository ppa:ansible/ansible

  Ansible is a radically simple IT automation platform that makes your applications and systems easier to deploy. Avoid writing scripts or custom code to deploy and update your applications— automate in a language that approaches plain English, using SSH, with no agents to install on remote systems.
 More info:
Press [ENTER] to continue or Ctrl-c to cancel adding it.
Get:1 focal-security InRelease [109 kB]
Hit:2 focal InRelease                                                                                                
Get:3 focal InRelease [18.0 kB]                                                                       
Get:4 focal-updates InRelease [114 kB]                                                                
Ign:5 stable InRelease                                                                         
Hit:6 focal InRelease                                                                                              
Hit:7 stable InRelease                                         
Get:8 focal-security/main amd64 DEP-11 Metadata [24.3 kB]                                     
Hit:9 stable Release                                                  
Get:10 focal-backports InRelease [101 kB]                
Get:12 focal/main i386 Packages [636 B]
Get:13 focal-security/universe amd64 DEP-11 Metadata [57.6 kB]                        
Get:14 focal-updates/main amd64 DEP-11 Metadata [264 kB]                          
Get:15 focal-updates/universe amd64 DEP-11 Metadata [302 kB]                               
Get:16 focal/main amd64 Packages [636 B]         
Get:17 focal-updates/multiverse amd64 DEP-11 Metadata [2,468 B]                    
Get:18 focal-backports/universe amd64 DEP-11 Metadata [1,768 B]          
Get:19 focal/main Translation-en [472 B]                                        
Fetched 995 kB in 2s (471 kB/s)                      
Reading package lists... Done

Next, update your repos:
$ sudo apt update
Here is what we see:

Hit:1 focal InRelease
Hit:2 focal InRelease                                                                                                                   
Ign:3 stable InRelease                                                   
Hit:4 focal-security InRelease                                                                           
Hit:5 focal-updates InRelease                                                                             
Hit:6 stable InRelease                              
Hit:7 focal InRelease 
Hit:8 stable Release
Hit:9 focal-backports InRelease
Reading package lists... Done
Building dependency tree       
Reading state information... Done
All packages are up to date.

It is time to install the latest version of Ansible, enter:
$ sudo apt install ansible

Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following additional packages will be installed:
  ieee-data python3-argcomplete python3-dnspython python3-jmespath python3-kerberos python3-libcloud python3-netaddr python3-ntlm-auth python3-requests-kerberos python3-requests-ntlm python3-selinux
  python3-winrm python3-xmltodict
Suggested packages:
  cowsay ipython3 python-netaddr-docs
The following NEW packages will be installed:
  ansible ieee-data python3-argcomplete python3-dnspython python3-jmespath python3-kerberos python3-libcloud python3-netaddr python3-ntlm-auth python3-requests-kerberos python3-requests-ntlm python3-selinux
  python3-winrm python3-xmltodict
0 upgraded, 14 newly installed, 0 to remove and 0 not upgraded.
Need to get 9,391 kB of archives.
After this operation, 88.6 MB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 focal/main amd64 python3-dnspython all 1.16.0-1build1 [89.1 kB]
Get:2 focal/main amd64 ieee-data all 20180805.1 [1,589 kB]
Get:3 focal/main amd64 python3-netaddr all 0.7.19-3 [235 kB]
Get:4 focal/universe amd64 ansible all 2.9.6+dfsg-1 [5,794 kB]
Get:5 focal/universe amd64 python3-argcomplete all 1.8.1-1.3ubuntu1 [27.2 kB]
Get:6 focal/main amd64 python3-jmespath all 0.9.4-2 [21.3 kB]
Get:7 focal/universe amd64 python3-kerberos amd64 1.1.14-3.1build1 [22.6 kB]
Get:8 focal/universe amd64 python3-libcloud all 2.8.0-1 [1,403 kB]
Get:9 focal/universe amd64 python3-ntlm-auth all 1.1.0-1 [19.6 kB]
Get:10 focal/universe amd64 python3-requests-kerberos all 0.12.0-2 [11.9 kB]
Get:11 focal/universe amd64 python3-requests-ntlm all 1.1.0-1 [6,004 B]
Get:12 focal/universe amd64 python3-selinux amd64 3.0-1build2 [139 kB]
Get:13 focal/universe amd64 python3-xmltodict all 0.12.0-1 [12.6 kB]
Get:14 focal/universe amd64 python3-winrm all 0.3.0-2 [21.7 kB]
Fetched 9,391 kB in 2s (3,890 kB/s)        
Selecting previously unselected package python3-dnspython.
(Reading database ... 329682 files and directories currently installed.)
Setting up python3-winrm (0.3.0-2) ...
Setting up ansible (2.9.6+dfsg-1) ...
Processing triggers for man-db (2.9.1-1) ...

Finding out the Ansible version

Type the following command:
$ ansible --version
My Ansible version running on Ubuntu 20.04 LTS desktop:

ansible 2.9.6
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3/dist-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.8.5 (default, Jul 28 2020, 12:59:40) [GCC 9.3.0]

Creating your hosts file

Ansible needs to know your remote server names or IP address. This information is stored in a file called hosts. The default is /etc/ansible/hosts. You can edit this one or create a new one in your $HOME directory:
$ sudo vi /etc/ansible/hosts
$ vi $HOME/hosts
Append your server’s DNS or IP address:



I have two groups. The first one named as webserver and other is called devservers.

Setting up ssh keys

You must configure ssh keys between your machine and remote servers specified in ~/hosts file:
$ ssh-keygen -t rsa -b 4096 -C "My ansisble key"
Use scp or ssh-copy-id command to copy your public key file (e.g., $HOME/.ssh/ to your account on the remote server/host:
$ ssh-copy-id -i $HOME/.ssh/
$ ssh-copy-id -i $HOME/.ssh/ root@
$ ssh-copy-id -i $HOME/.ssh/ root@
$ ssh-copy-id -i $HOME/.ssh/ root@
$ eval $(ssh-agent)
$ ssh-add

Now ansible can talk to all remote servers using ssh command.

Send ping requests to all servers

Just type the following command:
$ ansible -i ~/hosts -m ping all
Sample outputs: | SUCCESS => {
    "changed": false, 
    "failed": false, 
    "ping": "pong"
} | SUCCESS => {
    "changed": false, 
    "failed": false, 
    "ping": "pong"
} | SUCCESS => {
    "changed": false, 
    "failed": false, 
    "ping": "pong"

Find out uptime for all hosts

$ ansible -i hosts -m shell -a 'uptime' all
Sample outputs:

do-de.public | SUCCESS | rc=0  
 10:37:02 up 1 day,  8:39,  1 user,  load average: 0.95, 0.27, 0.12
do-blr-vpn | SUCCESS | rc=0 
 16:07:11 up 1 day,  8:43,  1 user,  load average: 0.01, 0.01, 0.00
ln.gfs01 | SUCCESS | rc=0  
 10:37:17 up 22 days,  5:30,  1 user,  load average: 0.18, 0.12, 0.05


  1. -i ~/hosts : Specify inventory host path. You can setup shell variable and skip the -i option. For e.g.: export ANSIBLE_HOSTS=~/hosts
  2. -m shell : Module name to execute such as shell, apt, yum and so on
  3. -a 'uptime' : Module arguments. For example, shell module will accept Unix/Linux command names. The apt module will accept options to update remote boxes using apt-get/apt command and so on.
  4. all : The all means “all hosts.” You can speificy group name such as devservers (ansible -i hosts -m shell -a 'uptime' dbservers) or host names too.

Update all Debian/Ubuntu server using apt module

Run the following command:
$ ansible -i ~/hosts -m apt -a 'update_cache=yes upgrade=dist' dbservers

Writing your first playbook

You can combine all modules in a text file as follows in yml format i.e. create a file named update.yml:

- hosts: dbservers
          - name: Updating host using apt
                    update_cache: yes
                    upgrade: dist

Here is my hosts file:
cat hosts
Sample outputs:

# Username for ssh connection
# Run commands as root user?  
# How do I become root user? Use sudo. 
# Password for sudo
# Password for sudo user i.e. ansible_user password
# See
# Read it from an encrypted file
# ansible_become_pass='{{ my_sudo_password }}' 

Now you can run it as follows:
$ ansible-playbook -i ~/hosts update.yml

Fig.01: Ansible playbook in action

Fig.01: Ansible playbook in action

You just install and configure latest version of Ansible on Ubuntu Linux and ran your first playbook too.

A note about Python version 3

Ansible needs python installed on a remote server. You can specify remote version of python using the following syntax in hosts file:
ansible_python_interpreter='/usr/bin/env python3'
For example here is my sample host file displayed using the cat command:
cat hosts

ansible_user='{{ my_user }}'
ansible_become_pass='{{ my_user_pass }}'
ansible_python_interpreter='/usr/bin/env python3'

Setting and configuring default Ansible option

The config file for ansible is located at /etc/ansible/ansible.cfg. Edit the file:
sudo vim /etc/ansible/ansible.cfg
Under [defaults] set display_skipped_hosts to False to hide displaying skipped task/host entries in a task in the default callback:

display_skipped_hosts = False

Next look up for [ssh_connection] to set up default ssh arguments:

ssh_args = -o ServerAliveInterval=30 -o ControlMaster=auto -o ControlPersist=60s

Save and close the file. We are reusing SSH connection to speed up remote login process using multiplexing by setting up ssh_args option. OpenSSH server connection drops out after few minutes of inactivity hence we are setting ServerAliveInterval to 30. We also used ControlPersist in conjunction with ControlMaster, specifies that the master connection should remain open in the background (waiting for future client connections) after the initial client connection has been closed.


That is all. Now you have a working ansible setup running on Ubuntu desktop/laptop and communication with remote servers. I suggest you learn how to write playbook and other stuff in the official documents.

🐧 Get the latest tutorials on Linux, Open Source & DevOps via RSS feed or Weekly email newsletter.

🐧 1 comment so far... add one

CategoryList of Unix and Linux commands
Disk space analyzersncdu pydf
File Managementcat
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network UtilitiesNetHogs dig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04
1 comment… add one
  • Eric Bursley Oct 25, 2017 @ 22:41

    Nice tutorial. On your update section that uses apt, you need to pass the -b and -K switches to become root and ask for the SUDO password. Otherwise the command will fail unless you are sshing in as root, which I wouldn’t recommend.

Leave a Reply

Your email address will not be published.

Use HTML <pre>...</pre> for code samples. Still have questions? Post it on our forum