DEV Community

Cover image for Starting with Ansible in Raspberry Pi
Project-42
Project-42

Posted on • Edited on

Starting with Ansible in Raspberry Pi

I have been thinking about starting to test Ansible in order to learn some of the basics, so what better way to do it in a easy to access system as a Raspberry Pi.

We won't be doing anything amazing here, just some basics processes on how to start with Ansible.

Lets start!!

Like I was mentioning earlier, lets use a small Raspberry Pi 2:

Linux raspi-2 4.19.97-v7+ #1294 SMP Thu Jan 30 13:15:58 GMT 2020 armv7l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Fri Feb  7 15:10:01 2020 from 192.168.0.21
    .',;:cc;,'.    .,;::c:,,.    P-42@raspi-2
   ,ooolcloooo:  'oooooccloo:    OS: Raspbian 10 buster
   .looooc;;:ol  :oc;;:ooooo'    Kernel: armv7l Linux 4.19.97-v7+
     ;oooooo:      ,ooooooc.     Uptime: 4d 23h 1m
       .,:;'.       .;:;'.       Packages: 635
       .... ..'''''. ....        Shell: 25900
     .''.   ..'''''.  ..''.      WM: Not Found
     ..  .....    .....  ..      CPU: ARMv7 rev 5 (v7l) @ 4x 900MHz
    .  .'''''''  .''''''.  .     GPU: BCM2708
  .'' .''''''''  .'''''''. ''.   RAM: 193MiB / 926MiB
  '''  '''''''    .''''''  '''
  .'    ........... ...    .'.
    ....    ''''''''.   .''.
    '''''.  ''''''''. .'''''
     '''''.  .'''''. .'''''.
      ..''.     .    .''..
            .'''''''
             ......
P-42@raspi-2:~#
'

Installing Ansible

We can use apt or your particular distro package manager, but doing that, we risk no getting the latest version available.
In some cases, I have to agree that is good idea, we make sure system is kept stable and the packages has been tested enough, but in technologies like Ansible, which is still changing so rapidly, I recommend you to go ahead in your tests and get the latest version, that way you will also learn to use those latest versions, which have some modules usage differences.

Lets see the version installed using apt in Raspbian

P-42@raspi-2:~#sudo apt-get update
Get:1 http://archive.raspberrypi.org/debian buster InRelease [25.1 kB]
Get:2 http://raspbian.raspberrypi.org/raspbian buster InRelease [15.0 kB]
[....]
Fetched 13.3 MB in 17s (806 kB/s)
Reading package lists... Done

P-42@raspi-2:~#sudo apt list ansible
Listing... Done
ansible/stable,now 2.7.7+dfsg-1 all [residual-config]
P-42@raspi-2:~#

Lets compare it with the version we get using pip3

P-42@raspi-2:~#pip3 search "ansible"
[...]
ansible (2.9.4)               - Radically simple IT automation

As you can see ,there are some difference, so I really recommend you to use pip for the installation

To Install Ansible using pip3, install pip3 first and then lets install Ansible for your current user:

P-42@raspi-2:~#sudo apt-get install python3-pip
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages were automatically installed and are no longer required:
  ieee-data libsodium23 python3-bcrypt python3-httplib2 python3-jinja2 python3-jmespath 
  [....]
  Setting up libpython3-dev:armhf (3.7.3-1) ...
Processing triggers for mime-support (3.62) ...
P-42@raspi-2:~#


P-42@raspi-2:~#pip3 install --user ansible
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Collecting ansible
  Using cached https://files.pythonhosted.org/packages/d7/d7/5afcb906038cd8a217ac57110055e27000c5cfe05ecafe969aaa119d1652/ansible-2.9.4.tar.gz
Requirement already satisfied: PyYAML in /usr/lib/python3/dist-packages (from ansible) (3.13)
Requirement already satisfied: cryptography in /usr/lib/python3/dist-packages (from ansible) (2.6.1)
Requirement already satisfied: jinja2 in /usr/lib/python3/dist-packages (from ansible) (2.10)
Building wheels for collected packages: ansible
  Running setup.py bdist_wheel for ansible ... done
  Stored in directory: /home/P-42/.cache/pip/wheels/f2/8a/6e/a433065001168c4ecbb5eb34224ec0af954e2a12aefe3da2cb
Successfully built ansible
Installing collected packages: ansible
Successfully installed ansible-2.9.4
P-42@raspi-2:~#

Installing Ansible using the --user option, will make that the binary will be available directly under your user home, and not in your root bin directory (/bin,/usr/bin..)

P-42@raspi-2:~#which ansible
/home/P-42/.local/bin/ansible
P-42@raspi-2:~#

For that, I recommend you to add your $user_home/.local/bin to your PATH environment:

P-42@raspi-2:~#env |grep bin
SHELL=/bin/bash
PATH=/home/P-42/gems/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games:/home/P-42/.local/bin
_=/usr/bin/env
P-42@raspi-2:~#

Ansible Project Configuration

Now that we have Ansible installed, lets set some basic configuration.

Create a directory for our first project where we are going to set the different configuration files and Ansible playbooks

P-42@raspi-2:~#mkdir Ansible
mkdir: created directory 'Ansible'
P-42@raspi-2:~# 

First file we are going to create, is an Ansible configuration file. This will make sure we are using correct inventory file and some specific options for this project.
In this case, we will use the inventory file in the local directory and will be connecting to the remote server as root. Additionally, will disable ssh-key check so we can connect to the servers without doing first ssh-key handshake (is a security risk, but will help us to destroy and deploy containers and VMs more rapidly in the future)

P-42@raspi-2:~/Ansible#cat ansible.cfg
[defaults]
# host_key_check diabled to avoid issues connecting to the Servers *Is a security risk*
host_key_checking = False

# Make user we are using local inventory and not the default one
inventory=./inventory

# Set default user to root
remote_user=root
P-42@raspi-2:~/Ansible#

Using --version attribute, will allow us to make sure we are suing correct configuration file:

P-42@raspi-2:~/Ansible#ansible --version
ansible 2.9.4
  config file = /home/P-42/Ansible/ansible.cfg
  configured module search path = ['/home/P-42/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/P-42/.local/lib/python3.7/site-packages/ansible
  executable location = /home/P-42/.local/bin/ansible
  python version = 3.7.3 (default, Dec 20 2019, 18:57:59) [GCC 8.3.0]
P-42@raspi-2:~/Ansible#

Lets create the inventory file with the list of hosts we will use for our project

P-42@raspi-2:~/ansible#cat inventory
[all]
server[1:4]

[webservers]
server1
server2

We can list all the hosts from our inventory

P-42@raspi-2:~/Ansible#ansible all --list-hosts
  hosts (4):
    server1
    server2
    server3
    server4
P-42@raspi-2:~/Ansible#

** These servers we are using are Docker containers we created using the following tutorial: https://dev.to/project42/install-and-deploy-docker-in-raspberry-pi-14kj

If we try the command ansible ping we will have errors, since we can not actually connect to our servers using ssh public keys

P-42@raspi-2:~/Ansible#ansible all -m ping
server2 | UNREACHABLE! => [
    "changed": false,
    "msg": "Failed to connect to the host via ssh: root@server2: Permission denied (publickey,password).",
    "unreachable": true
]
server1 | UNREACHABLE! => [
    "changed": false,
    "msg": "Failed to connect to the host via ssh: root@server1: Permission denied (publickey,password).",
    "unreachable": true
]
server3 | UNREACHABLE! => [
    "changed": false,
    "msg": "Failed to connect to the host via ssh: root@server3: Permission denied (publickey,password).",
    "unreachable": true
]
server4 | UNREACHABLE! => [
    "changed": false,
    "msg": "Failed to connect to the host via ssh: root@server4: Permission denied (publickey,password).",
    "unreachable": true
]
P-42@raspi-2:~/Ansible#

Deploying our first Playbook

Lets deploy the following Ansible Playbook in order to add our ssh public key to all servers root user

P-42@raspi-2:~/Ansible#cat ssh-key.yml
---
- name: Set authorized key for user root copying it from current user
  hosts: all
  tasks:
  - name: Install ssh-key
    authorized_key:
      user: root
      state: present
      key: "[ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') ]]"
P-42@raspi-2:~/Ansible#

In order to use Ansible without having ssh-keys in the different servers, we will need to install the package sshpass first

P-42@raspi-2:~/Ansible#sudo apt-get install sshpass -y
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages were automatically installed and are no longer required:
  ieee-data libsodium23 python3-bcrypt python3-httplib2 python3-jinja2 python3-jmespath python3-kerberos python3-libcloud python3-lockfile
  python3-markupsafe python3-nacl python3-netaddr python3-ntlm-auth python3-paramiko 
  [....]
Processing triggers for man-db (2.8.5-2) ...
P-42@raspi-2:~/Ansible#

Lets now deploy the playbook ssh-key.yml using the option -k so ansible will ask for the root password before connecting to the systems, allowing it to get the ssh-key added:

P-42@raspi-2:~/Ansible#ssh root@server1
Welcome to Ubuntu 16.04.6 LTS (GNU/Linux 4.19.97-v7+ armv7l)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

Last login: Wed Feb 12 18:20:18 2020 from 172.168.0.1
root@server1:~#

P-42@raspi-2:~/Ansible#ansible-playbook -k ssh-key.yml
SSH password:

PLAY [Set authorized key for user root copying it from current user] **************************************************************************

TASK [Gathering Facts] ************************************************************************************************************************
[DEPRECATION WARNING]: Distribution Ubuntu 16.04 on host server1 should use /usr/bin/python3, but is using /usr/bin/python for backward
compatibility with prior Ansible releases. A future Ansible release will default to using the discovered platform python for this host. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information. This feature will be removed in
version 2.12. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
ok: [server1]
[DEPRECATION WARNING]: Distribution Ubuntu 16.04 on host server4 should use /usr/bin/python3, but is using /usr/bin/python for backward
compatibility with prior Ansible releases. A future Ansible release will default to using the discovered platform python for this host. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information. This feature will be removed in
version 2.12. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
ok: [server4]
[DEPRECATION WARNING]: Distribution Ubuntu 16.04 on host server2 should use /usr/bin/python3, but is using /usr/bin/python for backward
compatibility with prior Ansible releases. A future Ansible release will default to using the discovered platform python for this host. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information. This feature will be removed in
version 2.12. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
ok: [server2]
[DEPRECATION WARNING]: Distribution Ubuntu 16.04 on host server3 should use /usr/bin/python3, but is using /usr/bin/python for backward
compatibility with prior Ansible releases. A future Ansible release will default to using the discovered platform python for this host. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information. This feature will be removed in
version 2.12. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
ok: [server3]

TASK [Install ssh-key] ************************************************************************************************************************
changed: [server2]
changed: [server4]
changed: [server1]
changed: [server3]

PLAY RECAP ************************************************************************************************************************************
server1                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
server2                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
server3                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
server4                    : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

P-42@raspi-2:~/Ansible#

and voila! we got our ssh-keys deployed and we can connect the systems without using the root password
(We can ignore does warning by enabling deprecation_warnings=False in ansible.cfg, but I recommend you to leave them to learn new things and get better usage of Ansible)

P-42@raspi-2:~/Ansible#ansible all -m ping
[DEPRECATION WARNING]: Distribution Ubuntu 16.04 on host server3 should use /usr/bin/python3, but is using /usr/bin/python for backward
compatibility with prior Ansible releases. A future Ansible release will default to using the discovered platform python for this host. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information. This feature will be removed in
version 2.12. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
server3 | SUCCESS => [
    "ansible_facts": [
        "discovered_interpreter_python": "/usr/bin/python"
    ],
    "changed": false,
    "ping": "pong"
]
[DEPRECATION WARNING]: Distribution Ubuntu 16.04 on host server2 should use /usr/bin/python3, but is using /usr/bin/python for backward
compatibility with prior Ansible releases. A future Ansible release will default to using the discovered platform python for this host. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information. This feature will be removed in
version 2.12. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
server2 | SUCCESS => [
    "ansible_facts": [
        "discovered_interpreter_python": "/usr/bin/python"
    ],
    "changed": false,
    "ping": "pong"
]
[DEPRECATION WARNING]: Distribution Ubuntu 16.04 on host server4 should use /usr/bin/python3, but is using /usr/bin/python for backward
compatibility with prior Ansible releases. A future Ansible release will default to using the discovered platform python for this host. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information. This feature will be removed in
version 2.12. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
server4 | SUCCESS => [
    "ansible_facts": [
        "discovered_interpreter_python": "/usr/bin/python"
    ],
    "changed": false,
    "ping": "pong"
]
[DEPRECATION WARNING]: Distribution Ubuntu 16.04 on host server1 should use /usr/bin/python3, but is using /usr/bin/python for backward
compatibility with prior Ansible releases. A future Ansible release will default to using the discovered platform python for this host. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information. This feature will be removed in
version 2.12. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
server1 | SUCCESS => [
    "ansible_facts": [
        "discovered_interpreter_python": "/usr/bin/python"
    ],
    "changed": false,
    "ping": "pong"
]
P-42@raspi-2:~/Ansible#

Like a mentioned, this is just a simple example of how to get started with Ansible in Raspberry Pi.

Top comments (3)

Collapse
 
jibunnokage profile image
Jibun-no-Kage

Apparently something has changed since this was published, the playbook to deploy the ssh key to each host fails with "invalid key specified: /home/pi/.ssh/id_rsa.pub". I validated that the desired key file does exist, in the correct location per the specification in the playbook. If I use ssh-copy-id to deploy the key to any given host, it is accepted, as expected, works as expected. Any suggestions?

Collapse
 
jibunnokage profile image
Jibun-no-Kage

I figured it out... you have a syntax issue in your playbook example...
You need to change the 'key' line. Remove the square brackets, which the left most is missing? And replace with braces. This allows the playbook to run correctly in Ansible core 2.12.1 for example.

Collapse
 
project42 profile image
Project-42

Yes, sorry, that is the problem with some projects like ansible where everything changes so fast :(
I didnt test this for a while, but I may try and see what can be changed