This September, RaspberryPi foundation has sold ten (10) Millions of unit. This small computer is amazing, you can setup very quickly several cool IoT projects. Since 2012, I bought all versions (B 256Mo, B 512Mo, B+, 2B, 3B) of RaspberryPi. I am a big fan of this product and you can find into this blog some projects I’ve made on top of this little computer. RaspberryPi version 3 comes with a wifi builtin interface, and this wifi interface can be configured as a Wifi Hotspot. I use it every day at home or at office. Today, I will show you how to configure a Wifi Hotspot with Ansible.
Howto setup a Hotspot Wifi w/ Ansible into a RaspberryPi 3
Prerequisites
For this lab, you need the following software :
- a RaspberryPi version 3
- with Raspbian and a ssh connection for pi user.
- Ansible installed into our system.
Clone git project
First of all, clone the git repo project.
git clone git@github.com:gautric/ansible-raspberrypi.git
cd ansible-raspberrypi
Ansible playbook
To install and configure our Wifi Hotspot, we gonna use a YAML file used by Ansible. This file is realy simple to understand. It’s a list of tasks, and each task will perform only one action like :
- installing package
- coping file
- enabling service
- restart device
By default Raspbian comes with pi user w/ correct sudo grant. In this playbook, Ansible uses pi user (remote_user: pi) and performs all commands with sudo (become: true).
Warning
As you can see wpa_passphrase and ssid must be defined. You will see how to do it with command line directly.
---
- name: Configure WIFI Hotspot for RaspberryPi 3
hosts: raspberrypi
remote_user: pi
vars:
wpa_passphrase: XXXXXXX
interface: wlan0
ssid: YYYYYYYY
ip_server: 10.0.0.1
netmask: 255.255.255.0
ip_dhcp_low: 10.0.0.2
ip_dhcp_high: 10.0.0.15
tasks:
- name: hostapd install
apt: name=hostapd state=present force=yes
become: true
- name: dnsmasq install
apt: name=dnsmasq state=present force=yes
become: true
- name: dnsmasq.conf
template:
src: template/dnsmasq.conf.j2
dest: /etc/dnsmasq.conf
backup: true
become: true
- name: hostapd.conf
template:
src: template/hostapd.conf.j2
dest: /etc/hostapd/hostapd.conf
backup: true
become: true
- name: hostapd
template:
src: template/hostapd.j2
dest: /etc/default/hostapd
backup: true
become: true
- name: rc.local
template:
src: template/rc.local.j2
dest: /etc/rc.local
backup: true
become: true
- name: dnsmasq service
service: name=dnsmasq enabled=yes state=started
become: true
- name: hostapd service
service: name=hostapd enabled=yes state=started
become: true
- name: restart machine
shell: sleep 2 && shutdown -r noww
async: 1
poll: 0
become: true
ignore_errors: true
We can also create template. Ansible will inject values into the template and copy the final file to destination.
interface={{ interface }}
hw_mode=g
channel=10
auth_algs=1
macaddr_acl=0
wpa=2
wpa_key_mgmt=WPA-PSK
wpa_pairwise=CCMP
rsn_pairwise=CCMP
wpa_passphrase={{ wpa_passphrase }}
ssid={{ ssid }}
Ansible Execution
To deploy configuration, Ansible provides ansible-playbook command line. You must configure hosts file, it includes all RaspberryPi hosts.
Ansible command line
$> ansible-playbook pi_wifi.yml --inventory-file=./hosts \
-u pi -v \
-e "ssid=RASPBERRY wpa_passphrase=1234567891011"
Warning
Please change wpa_passphrase and ssid correctly.
Ansible command line output
The command line output should look like the same.
$> ansible-playbook pi_wifi.yml --inventory-file=./hosts -u pi -v --diff -e "ssid=RASPBERRY wpa_passphrase=12345"
No config file found; using defaults
PLAY [raspberrypi] *************************************************************
TASK [setup] *******************************************************************
ok: [192.168.0.11]
TASK [hostapd install] *********************************************************
ok: [192.168.0.11] => {"cache_update_time": 0, "cache_updated": false, "changed": false}
TASK [dnsmasq install] *********************************************************
changed: [192.168.0.11] => {"cache_update_time": 0, "cache_updated": false, "changed": true, "stderr": "", "stdout": "Reading package lists...\nBuilding dependency tree...\nReading state information...\nThe following extra packages will be installed:\n dns-root-data dnsmasq-base libmnl0 libnetfilter-conntrack3\nThe following NEW packages will be installed:\n dns-root-data dnsmasq dnsmasq-base libmnl0 libnetfilter-conntrack3\n0 upgraded, 5 newly installed, 0 to remove and 0 not upgraded.\nInst libmnl0 (1.0.3-5 Raspbian:stable [armhf])\nInst libnetfilter-conntrack3 (1.0.4-1 Raspbian:stable [armhf])\nInst dns-root-data (2014060201+2 Raspbian:stable [all])\nInst dnsmasq-base (2.72-3+deb8u1 Raspbian:stable [armhf])\nInst dnsmasq (2.72-3+deb8u1 Raspbian:stable [all])\nConf libmnl0 (1.0.3-5 Raspbian:stable [armhf])\nConf libnetfilter-conntrack3 (1.0.4-1 Raspbian:stable [armhf])\nConf dns-root-data (2014060201+2 Raspbian:stable [all])\nConf dnsmasq-base (2.72-3+deb8u1 Raspbian:stable [armhf])\nConf dnsmasq (2.72-3+deb8u1 Raspbian:stable [all])\n", "stdout_lines": ["Reading package lists...", "Building dependency tree...", "Reading state information...", "The following extra packages will be installed:", " dns-root-data dnsmasq-base libmnl0 libnetfilter-conntrack3", "The following NEW packages will be installed:", " dns-root-data dnsmasq dnsmasq-base libmnl0 libnetfilter-conntrack3", "0 upgraded, 5 newly installed, 0 to remove and 0 not upgraded.", "Inst libmnl0 (1.0.3-5 Raspbian:stable [armhf])", "Inst libnetfilter-conntrack3 (1.0.4-1 Raspbian:stable [armhf])", "Inst dns-root-data (2014060201+2 Raspbian:stable [all])", "Inst dnsmasq-base (2.72-3+deb8u1 Raspbian:stable [armhf])", "Inst dnsmasq (2.72-3+deb8u1 Raspbian:stable [all])", "Conf libmnl0 (1.0.3-5 Raspbian:stable [armhf])", "Conf libnetfilter-conntrack3 (1.0.4-1 Raspbian:stable [armhf])", "Conf dns-root-data (2014060201+2 Raspbian:stable [all])", "Conf dnsmasq-base (2.72-3+deb8u1 Raspbian:stable [armhf])", "Conf dnsmasq (2.72-3+deb8u1 Raspbian:stable [all])"]}
The following extra packages will be installed:
dns-root-data dnsmasq-base libmnl0 libnetfilter-conntrack3
The following NEW packages will be installed:
dns-root-data dnsmasq dnsmasq-base libmnl0 libnetfilter-conntrack3
0 upgraded, 5 newly installed, 0 to remove and 0 not upgraded.
TASK [dnsmasq.conf] ************************************************************
changed: [192.168.0.11] => {"changed": true}
--- before
+++ after: dynamically generated
@@ -0,0 +1,2 @@
+interface=wlan0
+dhcp-range=10.0.0.2,10.0.0.5,255.255.255.0,12h
TASK [hostapd.conf] ************************************************************
changed: [192.168.0.11] => {"changed": true}
--- before
+++ after: dynamically generated
@@ -0,0 +1,11 @@
+interface=wlan0
+hw_mode=g
+channel=10
+auth_algs=1
+macaddr_acl=0
+wpa=2
+wpa_key_mgmt=WPA-PSK
+wpa_pairwise=CCMP
+rsn_pairwise=CCMP
+wpa_passphrase=1234567891011
+ssid=RASPBERRY
TASK [hostapd] *****************************************************************
changed: [192.168.0.11] => {"changed": true}
--- before: /etc/default/hostapd
+++ after: dynamically generated
@@ -7,12 +7,12 @@
# file and hostapd will be started during system boot. An example configuration
# file can be found at /usr/share/doc/hostapd/examples/hostapd.conf.gz
#
-#DAEMON_CONF=""
+DAEMON_CONF="/etc/hostapd/hostapd.conf"
# Additional daemon options to be appended to hostapd command:-
-# -d show more debug messages (-dd for even more)
-# -K include key data in debug messages
-# -t include timestamps in some debug messages
+# -d show more debug messages (-dd for even more)
+# -K include key data in debug messages
+# -t include timestamps in some debug messages
#
# Note that -B (daemon mode) and -P (pidfile) options are automatically
# configured by the init.d script and must not be added to DAEMON_OPTS.
TASK [rc.local] ****************************************************************
changed: [192.168.0.11] => {"changed": true}
--- before: /etc/rc.local
+++ after: dynamically generated
@@ -17,4 +17,12 @@
printf "My IP address is %s\n" "$_IP"
fi
+ifconfig wlan0 down
+ifconfig wlan0 10.0.0.1 netmask 255.255.255.0 up
+#ifconfig wlan0 inet6 add fc00::7262:7069:0003/7
+iwconfig wlan0 power off
+
+service dnsmasq restart
+service hostapd restart
+
exit 0
TASK [dnsmasq service] *********************************************************
changed: [192.168.0.11] => {"changed": true}
TASK [hostapd service] *********************************************************
changed: [192.168.0.11] => {"changed": true, "msg": "service state changed"}
PLAY RECAP *********************************************************************
192.168.0.11 : ok=10 changed=8 unreachable=0 failed=0
Et voila !!! If you reboot your raspberrypi, you should find a new Wifi Hotspot called RASPBERRY
Conclusion
I’ve created this Ansible playbook very quickly. The Ansible integration with a RaspberryPi is very easy because you just need a SSH connection to connect with. I think, I will continue to use Ansible with some of my RaspberryPi devices.