Using Ansible

How to combine and complement qbee with Ansible?

qbee-connect has built-in Ansible support in order to allow users to play out Ansible playbooks to remote qbee controlled devices even behind firewalls. This opens Ansible up for remote embedded Linux edge devices through the qbee integration. If really complex setups are needed playbooks can be used. For most other cases qbee will be sufficient and much simpler.

The advantage of Ansible is its flexibility and how many playbooks that are available. But it usually runs as a push based system. qbee is a pull based system initiating its connection from within a firewall or NAT. Thus it can communicate and connect from anywhere to the qbee backend. Through the built-in VPN an encrypted connection is established automatically. After that it is now possible to use the reverse secure tunnel to run Ansible without having a direct ssh connection. This connection is abstracted through the reverse tunnel created the by qbee VPN.

Use Ansible without having a direct ssh connection

Ansible is depending on having ssh access to the device. The qbee solution abstracts away this dependency opening up a lot of new use case opportunities. This finally allows users to easily use Ansible on embedded edge devices through a reverse secure tunnel.

The architecture of the system looks as follows:

!qbee-ansible-support-system-overview

Please install Ansible on your local control machine.

  1. Generate public/private key pair

    ssh-keygen -f ansible-key -b 521 -t ecdsa
    

    You don't want passphrase on the key, so just press enter.

  2. Copy the contents on ansible-key.pub and put that contents in "Authorized keys" under the "SSH keys" configuration. "User name" should be root.

    cat ansible-key.pub
    

    Please go to the configure menu and select SSH keys. In this example we play out the Ansible public key to all devices.

    !qbee-management-of-ssh-keys

    Check logs or audit tab and wait for the ssh to be distributed (will report back: "Writing authorized_keys for user root as it was not in compliance with policy.")

    !qbee-audit-ssh

    You can also run without the first to steps but then you need to add --ask-pass ansible-playbook command.

  3. Run qbee-connect. This will create a directory ~/.qbee/ansible_inventory in your home directory. This directory will reflect the qbee group and device structure. By connecting devices in qbee connect it will automatically populate the Ansible Inventory with mapped qbee devices. For the demo case here we connect the 2 devices in the "vRPI group". These are two Raspberry Pis called "raspberrypi-2" and "raspberrypi-3". Now the reverse secure tunnel is established. You can connect as many devices as you want to access with Ansible. We will also extend this feature in the future.

    !qbee-ansible-devices

    The resulting ~/.qbee/ansible_inventory looks as follows:

    [Production]
    [Production_industrialRPI]
    [Production_Systec]
    [vRPI]
    raspberrypi-2 ansible_connection=ssh ansible_ssh_host=localhost ansible_ssh_port=53843 ansible_ssh_user=root
    raspberrypi-3 ansible_connection=ssh ansible_ssh_host=localhost ansible_ssh_port=53848 ansible_ssh_user=root
    [vRPI_proxy_auth]
    [vRPI_Proxy_no_auth]
    [Ubuntu]
    [LoRaWAN_gateway]
    [LoRaWAN_gateway_Kerlink]
    [LoRaWAN_gateway_Kerlink_ifemto]
    [lab_devices]
    [lab_devices_warm_part]
    [lab_devices_cold_part]
    [LoRaWAN_gateway_Kerlink:children]
    LoRaWAN_gateway_Kerlink_ifemto
    [lab_devices:children]
    lab_devices_warm_part
    lab_devices_cold_part
    [Production:children]
    Production_industrialRPI
    Production_Systec
    [vRPI:children]
    vRPI_proxy_auth
    vRPI_Proxy_no_auth
    [LoRaWAN_gateway:children]
    LoRaWAN_gateway_Kerlink

    Please note the two connected devices with port mapping.

  4. Adapt the playbook to run on the group/role you want by editing the example playbook (helloworld.yml) and setting the "hosts: keyword" to match a group in ansible_inventory. If you keep "hosts: all" then it will run on all connected hosts.

    Please save this playbook as helloworld.yml to your user directory and adjust hosts accordingly:

    ---  
    - name: This is a hello-world example for qbee  
      hosts: vRPI  
      tasks:  
        - name: Create a file called '/tmp/qbee.txt' with the content 'Hello world from ansible over qbee-connect'.  
          copy:  
            content: Hello world from ansible over qbee-connect  
            dest: /tmp/qbee.txt
    
  5. Now you can run your helloworld.yml Ansible playbook.

    ansible-playbook -i ~/.qbee/ansible_inventory helloworld.yml --private-key=./ansible-key
    

    or without key distribution:

    ansible-playbook -i ~/.qbee/ansible_inventory helloworld.yml --ask-pass
    

    Executing the command yields the following output:

```
Carstens-MacBook-Pro:~ carsten$ ansible-playbook -i ~/.qbee/ansible_inventory helloworld.yml --private-key=./ansible-key

PLAY [This is a hello-world example for qbee]********************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************************************************
The authenticity of host '[localhost]:55321 ([127.0.0.1]:55321)' can't be established.
ECDSA key fingerprint is SHA256:W2NIzZg1CM9bOmlBkD9irIaBD12YnNJuCwVDxgkJGS4.
Are you sure you want to continue connecting (yes/no)? yes
ok: [raspberrypi-2]
ok: [raspberrypi-3]

TASK [Create a file called '/tmp/qbee.txt' with the content 'Hello world from ansible over qbee-connect'.] *******************************************
changed: [raspberrypi-3]
changed: [raspberrypi-2]

PLAY RECAP *******************************************************************************************************************************************
raspberrypi-2              : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
raspberrypi-3              : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
```
  1. Now the sentence 'Hello world from ansible over qbee-connect' should be available in the '/tmp/qbee.txt' on those two hosts. We will verify that by logging into the Raspberry Pi hosts through the remote console.

    !qbee-ansible-success