paramiko.SSHException: Incompatible ssh peer (no acceptable kex algorithm) ubuntu 14.04

I was trying to sftp some files using Python Paramiko on Ubuntu 14.04 and got the following error: “paramiko.SSHException: Incompatible ssh peer (no acceptable kex algorithm)”. It turns out that there is an incompatibility issue with OpenSSH 6.7 and Paramiko with a version less than 1.15.1. At the time of writing (November 2014) Ubuntu 14.04 came with 1.10.1.

To fix the issue, you need to upgrade Paramiko to at least 1.15.1. You can do this by using PIP which is a Python package management system. Here is how to you do this:

apt-get install python-pip

Do a quick version check of the Python libs like so:

pip freeze

Which gives the following output:


Then upgrade Paramiko using PIP.

pip install paramiko --upgrade

Voila. Paramiko sftp should now work.

In my case, I actually use Ansible to deploy changes across multiple servers. Ansible comes with a PIP module. You can automatically upgrade Paramiko across all servers like so:

## Python Packages Using PIP 
## We are doing this because we require the latest version of paramiko
- pip: name=paramiko state=latest

Ansible Diff Function

Ansible is a great tool for configuring servers. I only recently discovered the Ansible diff argument which can be used to check what changes are going to be made for a file. If you use this with the –check flag you can see what changes will be applied. I find this especially useful when coming back to a project after a break.

ansible-playbook paybook.yml –check –diff –limit

You can read the Ansible docs on this here:


How to add a mysql user with REPLICATION SLAVE privileges using Ansible

I just wanted to add a user to our database with REPLICATION SLAVE privileges. The Ansible module docs suggest that would do this:

mysql_user: user="replication_user" host="%" password="longpass" priv=*.*:REPLICATION SLAVE

However you get an error messages saying “this module requires key=value arguments”. The error was caused by the space between REPLICATION and SLAVE. The answer is to put the privilege in quotes:

mysql_user: user="replication_user" host="%" password="longpass" priv=*.*:"REPLICATION SLAVE"

Hope this helps someone.

Only running command if file doesn’t exist Ansible

I have a simple build script which installs wkhtmltophf on a server. However I only want this script to be run if the software isn’t already installed. Essentially, I want an if statement or check statement in Ansible. I.e. If file doesn’t exist then run this command.

I have read the Ansible documentation multiple times and it isn’t completely clear how to do this. Anyhow, here is the answer:

- name: If file don't exist run command
  command: /root/ creates=/usr/bin/wkhtmltopdf

This is command say “This command creates this file and so if the file doesn’t exist then run the command”.

I hope this helps someone

Ansible error fatal: must be stored as a dictionary/hash

I’ve been trying to setup group_vars in Ansible. My /group_vars/all file looked like;


When I ran my playbook it said:

Ansible error  "fatal: ...... must be stored as a dictionary/hash"

It would have been helpful if it had provided a better error message. Anyhow, basically, I had got the syntax wrong in group vars by putting “quotes” around the value:

some_variable: value 

Hope this helps someone.

Ansible vs Puppet – reasons for choosing Ansible

We have been using both Puppet and Ansible to configure our servers for several months. I have come to really love Ansible and I wanted to put down my reasons for finally choosing Ansible over Puppet.

Reason 1: Ansible is decentralised. With Puppet you need to maintain a central configuration server and install a Puppet Client (with root permissions) on each machine that you wish to configure. These individual client machines then connect to the configuration server and pull down their configurationa. Personally, as much as I love servers, I don’t want to maintain another server and client software. Ansible doesn’t require any central server. You just install and run it on your local machine. It doesn’t have any client software and configures the machines over ssh. This allows you to configure computers from anywhere, at anytime from any computer which has Ansible installed. This decentralised approach also means that Ansible once has done the configuration – it doesn’t sit there running in the background using power etc.

Reason 2: Ansible instantantly configures and provides feedback. . Puppet is based on a pull system which means the client ‘polls’ the server for changes to configurations. This means that there is a lag between writing a new configuration and having it pulled down to a server. For me this seem too complicated. Once I have written a configuration – I want to push it out immediately and check it worked.

Reason 3: Ansible configurations are ordered
Ansible is a little like a scripting language with commands running in a structured and ordered manner. Puppet on the other hand makes it hard to run ordered commands. It is possible by using dependencies. However, the simplicity of Ansible is, well, much simplier.

Reason 4: Ansible has a much gentler learning curve
It took me a much shorter period of time to learn Ansible compared to Puppet and achieve the same results. I’ve also found that it is much easier to explain Ansible to other people that I work with. For example – I’ve developed an Ansible script which configures a new development enviroment for an application that our team is working on. One of the members of the team saw the script in the repository and used it to configure his development enviroment with no prior knowledge of Ansible after 5 minutes of explaination from me. I’m sure that the reason for this is because Ansible script looks like other types of scripts and sysadmins and developers easierly understand scripts.

What are you thoughts?

How to install a list of packages with Ansible

I’ve been developing Ansible playbooks to help manage our Ubuntu servers. I wanted to install a list of package on a server using Ansible:

The old syntax:

 - name: Install list of packages
   action: apt pkg={{item}} state=installed
        - package1
        - package2
        - package3
        - etc

The new syntax:

 - name: Install list of packages
   apt: name={{item}} state=installed
        - package1
        - package2
        - package3
        - etc