Tuesday, January 24, 2017

Python Ansible Part1

In one of my previous posts I wrote that I couldn't use Fabric with Cisco IOS as I want, so I decided to try Ansible (the network I admin is heterogeneous but mostly is Linux, Cisco IOS).
Ansible is also used to automatise management process but it's more complex and thus more feature rich than Fabric.

Installation and understanding:
[admin@localhost ~]$ sudo pip install ansible
#In order to use `ansible_ssh_pass`:
[admin@localhost ~]$ sudo yum install sshpass

[admin@localhost ~]$ansible --version
ansible 2.2.1.0
config file =
configured module search path = Default w/o overrides

[admin@localhost ~]$ sudo mkdir  /etc/ansible
[admin@localhost ~]$ sudo vi /etc/ansible/hosts
[voip-srv] #host-group name
#Ansible will use `asterisk` as name for root@172.16.0.170:22
asterisk ansible_host=172.16.0.170 ansible_ssh_pass='123456'

[voip-srv:vars]
ansible_user=root
ansible_connection=ssh
ansible_port=22

[cisco-867]
c867-cc ansible_host=172.16.45.3 ansible_ssh_pass='123456'

[cisco-867:vars]
ansible_user=admin
ansible_connection=ssh
ansible_port=2200

When connecting to a server first time this message can appear:
"msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this.  Please add this host's fingerprint to your known_hosts file to manage this host."
To avoid this message, if you don't want to connect to this server manually via ssh and answer `yes` to `Are you sure you want to continue connecting`:
[admin@localhost ~]$ export ANSIBLE_HOST_KEY_CHECKING=False

Ansible Pattern
In Ansible pattern is a string describing which hosts to manage. It can be string (asterisk) or wildcard (all which equals to *) or regex (~(voip|web)-srv) or  (aster*) etc. We specify a module name after `-m`. `ping` module is not ICMP ping - it logins via SSH and verifies if appropriate python  version is installed:
[admin@localhost ~]$ ansible all   -m ping
asterisk | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
 [WARNING]: sftp transfer mechanism failed on [172.16.45.3]. Use ANSIBLE_DEBUG=1 to see detailed information

 [WARNING]: scp transfer mechanism failed on [172.16.45.3]. Use ANSIBLE_DEBUG=1 to see detailed information

c867-cc | FAILED! => {
    "failed": true,
    "msg": "failed to transfer file to \"` echo ~/.ansible/tmp/ansible-tmp-1485262768.12-203384291421785 `\" ) && sleep 0'\"/ping.py:\n\nAdministratively disabled.\n"
}

To view all available Ansible modules:
[admin@localhost ~]$ ansible-doc -l
To learn how to use module. Add module name after `ansible-doc`:
[admin@localhost ~]$ ansible-doc ios_config
> IOS_CONFIG

  Cisco IOS configurations use a simple block indent file syntax for segmenting configuration into sections.  This
  module provides an implementation for working with IOS configuration sections in a deterministic way.

  * note: This module has a corresponding action plugin.

Ansible Ad-Hoc Commands
We also can start using Ansible  without further configuration using `raw` module. In Ansible this is called Ad-Hoc commands:
[admin@localhost ~]$ ansible asterisk -m raw -a "asterisk -rx 'core show uptime'"
asterisk | SUCCESS | rc=0 >>
System uptime: 1 week, 1 day, 7 hours, 15 minutes, 21 seconds
Last reload: 1 week, 1 day, 7 hours, 15 minutes, 21 seconds
Shared connection to 172.16.0.170 closed.

To check state of the service on a host:
[admin@localhost ~]$ ansible asterisk -m service -a "name=asterisk state=started"
asterisk | SUCCESS => {
    "changed": false,
    "name": "asterisk",
    "state": "started"
}

Ansible Configuration File
Ansible configuration is processed in the below order (Ansible first searches for this files in the given order and then uses the first file found - no files merged):
  1. ANSIBLE_CONFIG (an environment variable)
  2. ansible.cfg (in the current directory)
  3.  .ansible.cfg (in the home directory)
  4. /etc/ansible/ansible.cfg

When installing via pip, files like ansible.cfg and ansible/hosts are not created automatically (but autogenerated when using yum or apt). We can create ansible.cfg manually or download it:
[admin@localhost ~]$ sudo touch /etc/ansible/ansible.cfg
OR
As on - https://ansible-tips-and-tricks.readthedocs.io/en/latest/ansible/install/
sudo wget -O /etc/ansible/ansible.cfg https://raw.githubusercontent.com/cyverse/ansible-tips-and-tricks/master/ansible.cfg


[admin@localhost ~]$ ansible --version
ansible 2.2.1.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides

Ansible supports this systems:
Linux, BSD, Windows (via WinRM and PowerShell), various networking devices (but most Ansible modules are either Desktop or Server OS oriented and won't work on networking devices - modules like `raw`  will remain working).

Note as of 2017-04-27:
for network equipment `ansible_connection` variable must be set to `local` not `ssh`.

6 comments:

  1. Could you tell how did you fix the warning message. I am getting that as a failure message and unable to ping. Though if i do sss@username.ip address , I am able to do. but the ping via ansible is failing. Please help!

    [root@centos7 testuser]# ansible ios -m ping
    [WARNING]: sftp transfer mechanism failed on [172.12.12.242]. Use ANSIBLE_DEBUG=1 to see detailed information

    [WARNING]: scp transfer mechanism failed on [172.12.12.242]. Use ANSIBLE_DEBUG=1 to see detailed information

    172.12.12.242 | FAILED! => {
    "failed": true,
    "msg": "failed to transfer file to \"` echo ~/.ansible/tmp/ansible-tmp-1493219295.06-139524108539472 `\" ) && sleep 0'\"/ping.py:\n\nAdministratively disabled.\n"
    }



    ReplyDelete
    Replies
    1. For Cisco equipment `ansible_connection=`variable must be `local`, not `ssh`. See below section to see effects of both settings:

      [admin@localhost ~]$ grep -E "^[^#].+(vars|connection)" /etc/ansible/hosts
      [cisco-867:vars]
      ansible_connection=ssh
      [admin@localhost ~]$ ansible c867-cc -m ping
      [WARNING]: sftp transfer mechanism failed on [172.16.45.3]. Use ANSIBLE_DEBUG=1 to see detailed information

      [WARNING]: scp transfer mechanism failed on [172.16.45.3]. Use ANSIBLE_DEBUG=1 to see detailed information

      c867-cc | FAILED! => {
      "failed": true,
      "msg": "failed to transfer file to \"` echo ~/.ansible/tmp/ansible-tmp-1493299620.15-225797636258696 `\" ) && sleep 0'\"/ping.py:\n\nAdministratively disabled.\n"
      }
      [admin@localhost ~]$ sudo vi /etc/ansible/hosts
      [admin@localhost ~]$ grep -E "^[^#].+(vars|connection)" /etc/ansible/hosts
      [cisco-867:vars]
      ansible_connection=local
      [admin@localhost ~]$ ansible c867-cc -m ping
      c867-cc | SUCCESS => {
      "changed": false,
      "ping": "pong"
      }

      Delete
  2. This comment has been removed by the author.

    ReplyDelete
  3. THANKS Dmitriy, I can ping the cisco device after changing the connection to local, but when I try to perform show version through ansible-playbook, I always get this massage, could you help with this? Many thanks!!!!!
    FAILED! => {"changed": false, "msg": "unable to open shell. Please see: https://docs.ansible.com/ansible/network_debug_troubleshooting.html#unable-to-open-shell"}

    ReplyDelete
  4. You are welcome. Alas now I've not enough time to work with Ansible.

    ReplyDelete
  5. To understand Ansible better for free, I recommend KIrk Byers free (or paid) courses on https://pynet.twb-tech.com/

    ReplyDelete