User’s guide


The goal of this configuration is to start dhclient and other system services (e.g. routing, ntpdate, ntpd, …) after the wifi interface connects to the network. The utility wpa_cli, running in the background, will be notified by wpa_supplicant when the interface connects or disconnects to/from the network. On such event wpa_cli executes the action file (-a action_file). See templates what pre-configured scripts are available. For example,, after the connection, starts dhclient, restarts routing, and optionally synchronizes date and time. This solves the potential problem of synchronizing date and time by settimeofday at boot time of a wireless-only system. If wpa_supplicant doesn’t manage to connect to the network by the time ntpdate is executed ntpdate will time-out. Then, in most systems, the ntpd service will start (see rcorder /etc/rc.d/*). When the hardware device has no battery and no RTC, the offset might be huge. In this case ntpd will reject the offset and will terminate itself, believing something very strange must have happened.


The role modifies scripts in /etc/rc.d


The most convenient way how to install an Ansible role is to use Ansible Galaxy CLI ansible-galaxy. The utility comes with the standard Ansible package and provides the user with a simple interface to the Ansible Galaxy’s services. For example, take a look at the current status of the role

shell> ansible-galaxy role info vbotka.freebsd_wpa_cli

and install it

shell> ansible-galaxy role install vbotka.freebsd_wpa_cli

Install the collections community.general and ansible.posix

shell> ansible-galaxy collection install ansible.posix
shell> ansible-galaxy collection install community.general

See also


Create simple playbook that calls the role (10) at a single host (2)

 1shell> cat playbook.yml
 2- hosts:
 3  gather_facts: true
 4  connection: ssh
 5  remote_user: admin
 6  become: true
 7  become_user: root
 8  become_method: sudo
 9  roles:
10    - vbotka.freebsd_wpa_cli

See also


Some tasks will display additional information when the variable wpacli_debug is enabled. Enable debug output either in the configuration

wpacli_debug: true

, or set the extra variable in the command

shell> ansible-playbook playbook.yml -e wpacli_debug=true


The debug output of this role is optimized for the yaml callback plugin. Set this plugin for example in the environment shell> export ANSIBLE_STDOUT_CALLBACK=yaml.


The tags provide the user with a very useful tool to run selected tasks of the role. To see what tags are available list the tags of the role with the command

shell> ansible-playbook playbook.yml --list-tags

playbook: playbook.yml

play #1 ( TAGS: [] TASK TAGS:
   [always, wpacli_action_script, wpacli_assert, wpacli_debug,
   wpacli_packages, wpacli_pid_dir, wpacli_rc,
   wpacli_rc_defaults_patch, wpacli_rc_networksubr_patch,
   wpacli_rc_script, wpacli_rcconf, wpacli_wpa_cli]


  • Display the list of the variables and their values with the tag wpacli_debug (when the debug is enabled wpacli_debug: true)

 shell> ansible-playbook playbook.yml -t wpacli_debug
  • See what packages will be installed

 shell> ansible-playbook playbook.yml -t wpacli_packages --check
  • Install packages and exit the play

 shell> ansible-playbook playbook.yml -t wpacli_packages



See also

Development and testing

In order to deliver an Ansible project it’s necessary to test the code and configuration. The tags provide the administrators with a tool to test single tasks’ files and single tasks. For example, to test a single task at a single remote host test_01, create the playbook

shell> cat playbook.yml
- hosts: test_01
  become: true
    - vbotka.freebsd_wpa_cli

Customize configuration in host_vars/test_01/wpa-cli.yml and check the syntax

shell> ansible-playbook playbook.yml --syntax-check

Then dry-run the selected task and see what will be changed. Replace <tag> with valid tag or with a comma-separated list of tags

shell> ansible-playbook playbook.yml -t <tag> --check --diff

When all seems to be ready run the command. Run the command twice and make sure the playbook and the configuration is idempotent

shell> ansible-playbook playbook.yml



Create wpa_cli action file (default /root/bin/


See also



Configuration of /etc/rc.d


See also


 1--- rc.conf.orig	2019-01-06 23:53:26.848957000 +0100
 2+++ rc.conf	2019-01-06 23:55:58.354651000 +0100
 3@@ -133,6 +133,9 @@
 4 wpa_supplicant_program="/usr/sbin/wpa_supplicant"
 5 wpa_supplicant_flags="-s"	# Extra flags to pass to wpa_supplicant
 6 wpa_supplicant_conf_file="/etc/wpa_supplicant.conf"
10 #
11 firewall_enable="NO"		# Set to YES to enable firewall functionality
12 firewall_script="/etc/rc.firewall" # Which script to run to set up the firewall


 1--- network.subr.orig	2019-01-06 23:13:49.382184000 +0100
 2+++ network.subr	2019-01-06 23:13:43.162190000 +0100
 3@@ -222,6 +222,7 @@
 4 	if wpaif $1; then
 5 		/etc/rc.d/wpa_supplicant start $1
 6 		_cfg=0		# XXX: not sure this should count
 7+		/etc/rc.d/wpa_cli start $1
 8 	elif hostapif $1; then
 9 		/etc/rc.d/hostapd start $1
10 		_cfg=0
11@@ -252,6 +253,7 @@
12 	_cfg=1
14 	if wpaif $1; then
15+		/etc/rc.d/wpa_cli stop $1
16 		/etc/rc.d/wpa_supplicant stop $1
17 		_cfg=0
18 	elif hostapif $1; then


Default variables

The default variables are stored in the file defaults/main.yml. These variables can be customized in the file vars/main.yml. The file vars/main.yml will be preserved by the update of the role.


  • Don’t make any changes to the file defaults/main.yml. The changes will be overwritten by the update of the role. Customize the default values in the file vars/main.yml.

See also

  • The examples of the customization vars/main.yml.sample


  2# defaults for vbotka.freebsd_wpa_cli
  4# Install wpacli_packages
  5wpacli_install: true
  7# Enable wpa_cli in rc.conf
  8# (It's a string used in rc.conf. It's not a boolean type.
  9# Options are "YES" or "NO" uppercase mandatory.
 10wpacli_enable: "YES"
 12# Enable test of supported OS versions listed in wpacli_versions_tested
 13wpacli_assert_enable: true
 15# Enable debug output
 16wpacli_debug: false
 18# Create backups of modified files
 19wpacli_backup_conf: false
 21# List of supported OS versions
 23  - "11.3"
 24  - "11.4"
 25  - "12.1"
 26  - "12.2"
 27  - "12.3"
 28  - "12.4"
 29  - "13.0"
 30  - "13.1"
 31  - "13.2"
 32  - "13.3"
 33  - "14.0"
 35# Installation method.
 36# Options are "packages" for binary packages or "ports"
 37freebsd_install_method: packages
 39# If installation method is "ports" use binary packages if
 40# available
 41freebsd_use_packages: true
 43# Number of times an unsuccessful installation is retried
 44freebsd_install_retries: 10
 46# Delay in seconds an unsuccessful installation is retried
 47freebsd_install_delay: 5
 49# Path to wpa_cli.
 50# '/usr/sbin/wpa_cli' is included in the base system. Change to
 51# '/usr/local/sbin/wpa_cli' to use the binaries installed by
 52# security/wpa_supplicant.
 53# Change together with the path to wpa_supplicant. Optionaly use
 54# vbotka.freebsd_postinstall to accomplish this.
 55#   - include_role:
 56#       name: vbotka.freebsd_postinstall
 57#       tasks_from: wpasupplicant.yml
 58wpacli_program: /usr/sbin/wpa_cli
 60# Install packages
 62  - security/wpa_supplicant
 64# wpa_cli PID
 65wpacli_pid_dir: /var/run/wpa_cli
 66wpacli_pid_dir_owner: root
 67wpacli_pid_dir_group: wheel
 68wpacli_pid_dir_mode: "0750"
 70# Create wpa_cli action script
 71wpacli_action_script: false
 72# Path to the action script
 73wpacli_action_script_dir: /root/bin
 74wpacli_action_script_dir_owner: root
 75wpacli_action_script_dir_group: wheel
 76wpacli_action_script_dir_mode: "0755"
 77# Filename of the action script
 79# Ownership and permissions of the action script
 80wpacli_action_script_owner: root
 81wpacli_action_script_group: wheel
 82wpacli_action_script_mode: "0750"
 83# Action script template
 85# Paramters used in the template
 86wpacli_action_script_log_to_file: false
 87wpacli_action_script_logfile: /tmp/wpa_action.$ifname
 88wpacli_action_script_ntp_set: false
 89wpacli_action_script_ntp_server: ""
 90wpacli_action_script_ntpdate_flags: -b
 92# Parameters in /etc/rc.conf
 93wpacli_ctrl_interface: /var/run/wpa_supplicant
 95  - { key: wpa_cli_enable, val: "{{ wpacli_enable }}" }
 96  - { key: wpa_cli_program, val: "{{ wpacli_program }}" }
 97  - { key: wpa_cli_ctrl_interface, val: "{{ wpacli_ctrl_interface }}" }
 98  - { key: wpa_cli_action_file, val: "{{ wpacli_action_script_dir }}/{{ wpacli_action_script_file }}" }
100# See role: vbotka.freebsd_postinstall task: wpasupplicant.yml
101# fp_wpasupplicant_conf_ctrl_interface: "/var/run/wpa_supplicant"
103# EOF

Best practice

Test syntax

shell> ansible-playbook playbook.yml --syntax-check

See what variables will be used

shell> ansible-playbook playbook.yml -t wpacli_debug -e wpacli_debug=true

Dry-run, display differences and display variables

shell> ansible-playbook playbook.yml -e wpacli_debug=true --check --diff

Install packages

shell> ansible-playbook playbook.yml -t wpacli_packages -e wpacli_install=true

Run the playbook

shell> ansible-playbook playbook.yml

Test the idem-potency. The role and the configuration data shall be idempotent. Once the installation and configuration have passed there should be no changes reported by ansible-playbook when running the playbook repeatedly. Disable debug, and install to speedup the playbook and run the playbook again.

 shell> ansible-playbook playbook.yml