Admin... by accident!

You may have chosen to be an admin. I didn't!

  • Home
  • FreeBSD
  • GNU/Linux
  • Security
  • Network
  • Virtualization
  • Politics
  • Github
  • Donate
  • Me

How to install Ansible on FreeBSD

May 14, 2020 by Albert Valbuena

Ansible is a very useful tool geared to system’s configuration and applications deployment. In this how to install Ansible on FreeBSD I will briefly explain what the tool is, what it does, what it does not and how to install it on FreeBSD. I will also demonstrate very basic use and on a later article I will write about software deployment and maintenance through Ansible.

Ansible is open source software and actively being developed by Red Hat the company behind the most relevant GNU/Linux product on the market the Red Hat Linux OS and its cousins CentOS and Fedora. These guys know one thing or two about controlling hundreds of servers at once and in the process everyone has got very aware of the issues those ‘fine tunned’ shell scripts can arise. So they came out with a solution similar to Puppet or Chef in functionality but with a different model.

Ansible is agentless. Meaning the client boxes do not need special software to be installed and received the configuration changes or application deployment on them. In that sense Ansible is a more of a ‘push’ tool than a ‘pull’ one, although uses both. A master node needs Ansible and Python installed on it to control the clients, or hosts. Clients will receive the changes via SSH connections and will need Python to get going. However one can set Python on them remotely as I’ll demonstrate below. The whole thing works using Playbooks, which are set on the master node and serve as a configuration template for the client nodes to follow.

If you find the articles in Adminbyaccident.com useful to you, please consider making a donation.

Use this link to get $200 credit at DigitalOcean and support Adminbyaccident.com costs.

Get $100 credit for free at Vultr using this link and support Adminbyaccident.com costs.

Mind Vultr supports FreeBSD on their VPS offer.

Playbooks are configuration files that system and network administrators alike can write in order to control their environments, no matter how large those are. In there they will declare the state of the systems they want them to be. The tool is simple and has some advantages over old school shell scripts.

– Playbooks are easy to write.

– They provide consistency. Ever found the same line written twice or more times on the same config file?

– Changes are not applied if they aren’t needed.

– Can be applied to groups of servers or individually.

– Simplification of the abstractions at hand.

– Uniformity across the environment.

Things Ansible will not do for you in any case:

– Reduce your workload. Playbooks do not write themselves as shell scripts don’t either.

– Solve all your mistakes. Ansible is safer to work with, but issues may arise if you make a mistake.

– Copy files from box A to box B, unless they are found in the master node.

– Grab your existing shell scripts and magically convert them into playbooks. It would be nice though, wouldn’t it?

FreeBSD is not a first citizen on Ansible land however it works beyond ‘fairly good’, although not being excellent as it is on the Linux world. This said most available modules work on all the BSDs, not just FreeBSD, so people is using the tool, because it works.

In this how to install Ansible on FreeBSD guide you’ll read about:

– The prerequisites.

– How to install Ansible on the master node.

– How to configure Ansible on the master node.

– How to install Python on the client nodes.

– How to write a very simple Ansible Playbook.

– References to gather further information.

Prerequisites

This is the list of prerequisites one needs to fulfill before using Ansible.

– One FreeBSD node as a ‘master node’.

– One or more FreeBSD node or jail as ‘client nodes’.

– Every box needs the OpenSSH service to be on.

– One non-root user on each client, accessible from the master.

– This user must be on the ‘wheel’ group’.

– An SSH key pair, with the public keys installed on each client so the master can access the clients.

On my setup I will be using three VMs on VirtualBox, but you may want to use FreeBSD Jails instead. BSDVM will be the master node and FreeBSD-A and FreeBSD-B will be the client nodes. So the first two prerequisites are done.

To enable the SSH service we need to add one config line into the /etc/rc.conf file, which is one of the master configuration ones in the BSD realm. We’ll first check if it’s already running.

$ grep -n 'ssh' /etc/rc.conf

If some output comes out there is nothing you have to do. So you can jump into adding the ansible user. If there’s output it should be similar to:

[albert@BSDVM ~]$ grep -n 'ssh' /etc/rc.conf

4:sshd_enable="YES"

[albert@BSDVM ~]$

If there is no result you need to start up the service. First append the missing configuration line into /etc/rc.conf with this command:

$ sudo sysrc sshd_enable="YES"

Once the configuration is set up you can start the SSH service.

$ sudo service sshd start

All the three VMs in my setup have a user created just for ansible. The user is conveniently named ‘ansible’ but you can choose whatever you see fit. I’ll show you how to add a user on FreeBSD, although there is enough information around the internet and on the official documentation for this though.

root@BSDVM:~ # adduser

Username: ansible

Full name: ansible

Uid (Leave empty for default):

Login group [ansible]: wheel

Login group is wheel. Invite ansible into other groups? []:

Login class [default]:

Shell (sh csh tcsh git-shell bash rbash nologin) [sh]: bash

Home directory [/home/ansible]:

Home directory permissions (Leave empty for default):

Use password-based authentication? [yes]:

Use an empty password? (yes/no) [no]:

Use a random password? (yes/no) [no]:

Enter password:

Enter password again:

Lock out the account after creation? [no]:

Username : ansible

Password : *****

Full Name : ansible

Uid : 1002

Class :

Groups : wheel

Home : /home/ansible

Home Mode :

Shell : /usr/local/bin/bash

Locked : no

OK? (yes/no): yes

adduser: INFO: Successfully added (ansible) to the user database.

Add another user? (yes/no): no

Goodbye!

root@BSDVM:~ #

Once I’ve created the ‘ansible’ user on each box I create the SSH key pair on the BSDVM master node.

[albert@BSDVM ~]$ su - ansible

Password:

Any user that is a member of the wheel group can use "su -" to simulate

a root login. You can add a user to the wheel group by editing /etc/group.

-- Konstantinos Konstantinidis <[email protected]>

[ansible@BSDVM ~]$ ssh-keygen -t rsa

Generating public/private rsa key pair.

Enter file in which to save the key (/home/ansible/.ssh/id_rsa):

Created directory '/home/ansible/.ssh'.

Enter passphrase (empty for no passphrase):

Enter same passphrase again:

Your identification has been saved in /home/ansible/.ssh/id_rsa.

Your public key has been saved in /home/ansible/.ssh/id_rsa.pub.

The key fingerprint is:

SHA256:hrBFvEcg2t8CcrPoP9821clm8EckimbNYSwJ0llQ8T0 ansible@BSDVM

The key's randomart image is:

+---[RSA 2048]----+

| oo=B++ |

| o ++ +.+.. . |

| o * .o *.oEo |

| + O.o= = .. |

| . o ++S = o |

| . o . B . |

| . . o . |

| .. .o |

| .o.... |

+----[SHA256]-----+

[ansible@BSDVM ~]$

Now the key pair has been created into the ansible home directory (/usr/home/ansible/.ssh) it’s time to place the public key inside every client. What and where.

The what.

My public key on the master node is:

[ansible@BSDVM ~]$ cat /home/ansible/.ssh/id_rsa.pub

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsIpDAeudRoSakzVbPBmbJpetXDv3BIKPWe4+ZVPCJ3BtdGY1YOnSGdB5TVnsk8UqvxKRS/msyF0/+SfxSqTu23ixNMqExfuoR3puKMys+DOiGPNrQTXGuNKE2z/2/CiiOswZ+/WQ7fJf4eUlX7sfK3gTtHqBuyzN6Loc6irwppoed0HCF/YWPi+ZuZelZ6TvDLvQN85WJYmlHcoZ3F9aUjch9o3HBEAaXi3x7te2f10up8c8UwvEa8l4w+k58V/Ld0Fms1at6BpwO1GwQz/iQPfmQ/CDmP+yKlBAHowoAJwurO987bsRbUMPdXymEgE0SKhmZB+Rf4M12whQS2rqr ansible@BSDVM

[ansible@BSDVM ~]$

The where.

Place the public into each client in the following path /home/ansible/.ssh/authorized_keys. You may need to create the path first though.

[ansible@FreeBSD-B ~]$ mkdir .ssh

[ansible@FreeBSD-B ~]$ cd .ssh

[ansible@FreeBSD-B ~/.ssh]$

[ansible@FreeBSD-B ~/.ssh]$ vi authorized_keys

[ansible@FreeBSD-B ~/.ssh]$ cat authorized_keys

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCsIpDAeudRoSakzVbPBmbJpetXDv3BIKPWe4+ZVPCJ3BtdGY1YOnSGdB5TVnsk8UqvxKRS/msyF0/+SfxSqTu23ixNMqExfuoR3puKMys+DOiGPNrQTXGuNKE2z/2/CiiOswZ+/WQ7fJf4eUlX7sfK3gTtHqBuyzN6Loc6irwppoed0HCF/YWPi+ZuZelZ6TvDLvQN85WJYmlHcoZ3F9aUjch9o3HBEAaXi3x7te2f10up8c8UwvEa8l4w+k58V/Ld0Fms1at6BpwO1GwQz/iQPfmQ/CDmP+yKlBAHowoAJwurO987bsRbUMPdXymEgE0SKhmZB+Rf4M12whQS2rqr ansible@BSDVM

[ansible@FreeBSD-B ~/.ssh]$

We now have all the prerequisites satisfied. Three nodes, one master and two clients. The SSH service is running on all three. A non-root user on the nodes. That user is on the ‘wheel group’. A key-pair for that user on the three boxes.

Install Ansible on the Master Node

There are several versions of Ansible available on FreeBSD. I’ll use the latest in this example but you may be familiar with a particular version or have seen someone using some specific. Choose your poison. I tend to use the latest, not just to have the most newer features.

[albert@BSDVM ~]$ sudo pkg install python37 py37-ansible

Updating FreeBSD repository catalogue...

FreeBSD repository is up to date.

All repositories are up to date.

Checking integrity... done (0 conflicting)

The following 14 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:

libsodium: 1.0.18

python37: 3.7.7

py37-Babel: 2.8.0

py37-Jinja2: 2.10.1

py37-MarkupSafe: 1.1.1

py37-ansible: 2.9.7

py37-bcrypt: 3.1.7

py37-jmespath: 0.9.5

py37-netaddr: 0.7.19_1

py37-paramiko: 2.7.1

py37-pyasn1: 0.4.7

py37-pynacl: 1.3.0

py37-pytz: 2019.3,1

py37-yaml: 5.3.1

Number of packages to be installed: 14

The process will require 182 MiB more space.

Proceed with this action? [y/N]: y

Once Python 3.7 and Ansible are installed we can start the configuration.

Two key files have been placed into /usr/local/share/examples.

/usr/local/share/examples/py37-ansible/hosts

/usr/local/share/examples/py37-ansible/ansible.cfg

We will copy them and place them into the /etc/ directory. However, this is FreeBSD and the /etc/ directory is reserved for the OS. Applications have their own /etc/ directory placed in /usr/local/etc.

First we create the ansible directory.

$ sudo mkdir /usr/local/etc/ansible

Now we copy the files.

$ sudo cp /usr/local/share/examples/py37-ansible/hosts /usr/local/etc/ansible

$ sudo cp /usr/local/share/examples/py37-ansible/ansible.cfg /usr/local/etc/ansible

Once the tool has been installed, let’s configure it.

Configure Ansible on the Master Node

Time for configuration bits in this how to install Ansible on FreeBSD. The ‘hosts’ file in the ansible directory is very important. In there I will declare the list of nodes who will act as clients. How will the master connect to those, with what user and with what key.

At the end of the ‘hosts’ file in Ansible I’ve set my two nodes as one group called ‘freebsd’.

[freebsd]

freebsd-a ansible_ssh_host=192.168.1.133

freebsd-b ansible_ssh_host=192.168.1.134

One can avoid naming them and just place the IPs straight away, but for the sake of clarity I’ve decided to include this as well.

Undertneath of this group declaration I’ve also set the variables.

[freebsd:vars]

ansible_python_interpreter=/usr/local/bin/python3.7

ansible_user=ansible

ansible_become=yes

ansible_become_method=sudo

ansible_connection=ssh

ansible_ssh_private_key_file=/usr/home/ansible/.ssh/id_rsa

These are important. The first one is the python binary location, the user that the master node will connect to the client with come next, followed by if the user can become ‘root’ using ‘sudo’ and finally the authentication method, set here with ‘ssh’ and the private key location as well.

Furthermore you can make your own arrangements. If you read the ‘hosts’ file in Ansible you will see some examples that can help you out on your particular set up.

Before moving on I’ve set one change in the main Ansible configuration file. I’ve disabled SSH key host checking just for the sake of testing, by removing the ‘#’ at the beginning of the line. You can find it with the following command.

$ grep -n 'host_key_checking' ansible.cfg

Mine sits on line 71 and reads as follows:

[albert@BSDVM ~/ansible]$ grep -n 'host_key_checking' ansible.cfg

71:host_key_checking = False

[albert@BSDVM ~/ansible]$

Once Ansible is installed on the master node I can move forward and use the ‘raw’ module in order to install Python on the client nodes without having to log in into every single one of them. Just from the master node.

Install Python on the Client Nodes

Another critical step on this how to install Ansible on FreeBSD guide. Ansible has a module called ‘raw’. It is useful in this case to somehow ‘force’ the installation of Python on the clients. This is the command, same as in the official Ansible documentation and adatpted for my example.

$ sudo ansible -m raw -a "pkg install -y python37" freebsd

The output I’ve received:

[albert@BSDVM /usr/local/etc/ansible]$ sudo ansible -m raw -a "pkg install -y python37" freebsd

freebsd-b | CHANGED | rc=0 >>

Updating FreeBSD repository catalogue...

FreeBSD repository is up to date.

All repositories are up to date.

Checking integrity... done (0 conflicting)

The following 3 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:

libffi: 3.2.1_3

python37: 3.7.7

readline: 8.0.4

Number of packages to be installed: 3

The process will require 112 MiB more space.

[1/3] Installing readline-8.0.4...

[1/3] Extracting readline-8.0.4: 100%

[2/3] Installing libffi-3.2.1_3...

[2/3] Extracting libffi-3.2.1_3: 100%

[3/3] Installing python37-3.7.7...

[3/3] Extracting python37-3.7.7: 100%

=====

Message from python37-3.7.7:

--

Note that some standard Python modules are provided as separate ports

as they require additional dependencies. They are available as:

py37-gdbm databases/py-gdbm@py37

py37-sqlite3 databases/py-sqlite3@py37

py37-tkinter x11-toolkits/py-tkinter@py37

Shared connection to 192.168.1.134 closed.

freebsd-a | CHANGED | rc=0 >>

Updating FreeBSD repository catalogue...

FreeBSD repository is up to date.

All repositories are up to date.

Checking integrity... done (0 conflicting)

The following 3 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:

libffi: 3.2.1_3

python37: 3.7.7

readline: 8.0.4

Number of packages to be installed: 3

The process will require 112 MiB more space.

[1/3] Installing readline-8.0.4...

[1/3] Extracting readline-8.0.4: 100%

[2/3] Installing libffi-3.2.1_3...

[2/3] Extracting libffi-3.2.1_3: 100%

[3/3] Installing python37-3.7.7...

[3/3] Extracting python37-3.7.7: 100%

=====

Message from python37-3.7.7:

--

Note that some standard Python modules are provided as separate ports

as they require additional dependencies. They are available as:

py37-gdbm databases/py-gdbm@py37

py37-sqlite3 databases/py-sqlite3@py37

py37-tkinter x11-toolkits/py-tkinter@py37

Shared connection to 192.168.1.133 closed.

[albert@BSDVM /usr/local/etc/ansible]$

As you can see, it worked. Now that Python is present on the client nodes, we can test Ansible is working and the client nodes are reachable by pinging them with Ansible. This is the command for that.

$ sudo ansible -m ping freebsd

This is my received output.

[albert@BSDVM /usr/local/etc/ansible]$ sudo ansible -m ping freebsd

freebsd-a | SUCCESS => {

"changed": false,

"ping": "pong"

}

freebsd-b | SUCCESS => {

"changed": false,

"ping": "pong"

}

[albert@BSDVM /usr/local/etc/ansible]$

Write a Simple Playbook

First things first. What is a Playbook? Think of a playbook of a reference template which states and reflects in what conditions the node clients have to be configured. What applications should be in them, what configuration files should be in place and what critical configuration bits have to be in such files.

Very interestingly one can run a new playbook specifically for a set of nodes, like in our example. The first time changes will be committed, however the second time we launch the same exact playbook the system will not change at all. New lines won’t be placed underneath the previous ones as often happens when one forgets if the shell script was lauched in the past in a particular node.

Playbooks are key in Ansible and there is a lot to read about. The list of modules tackles almost every aspect of system’s configuration. There are dedicated modules for Cisco products, Fortinet, Windows, you name it and they have it. All playbooks are written in YAML format, a human-readable data-serialization language.

I’ll use a playbook to install Apache HTTP in the freebsd group of servers. For exmaple this could well be a group of servers called ‘webservers’.

This is the beginning of this test playbook.

---

# Install minimal packages for the webservers

- hosts: freebsd

tasks:

At the beginning of every playbook we need to place three dashes. Then we have to declare what boxes does this has to be ‘played’ in. After that we need to detail one or a series of tasks.

- name: Install Apache HTTP
pkgng:
name: apache24

- name: Enable Apache HTTP
lineinfile:
dest: /etc/rc.conf
backup: yes
line: apache24_enable="YES"

- name: Start Apache HTTP
service:
name: apache24
enabled: yes
state: started

If we take a closer look there are three tasks in this play. The first is installing Apache HTTP, the second enables it and the third starts up the service.

I’ll write this playbook as apache_install.yml inside /usr/local/etc/ansible and play it.

[albert@BSDVM /usr/local/etc/ansible]$ sudo ansible-playbook apache_install.yml

PLAY [freebsd] ****************************************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************************************

ok: [freebsd-a]

ok: [freebsd-b]

TASK [Install Apache HTTP] ****************************************************************************************************************

changed: [freebsd-b]

changed: [freebsd-a]

TASK [Enable Apache HTTP] *****************************************************************************************************************

ok: [freebsd-b]

ok: [freebsd-a]

TASK [Start Apache HTTP] ******************************************************************************************************************

ok: [freebsd-a]

ok: [freebsd-b]

PLAY RECAP ********************************************************************************************************************************

freebsd-a : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

freebsd-b : ok=4 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

[albert@BSDVM /usr/local/etc/ansible]$

As it can be seen from the output the master node first makes contact with the clients, gathers information about their status and configuration and then applies the necessary changes.

Visting one of the two client nodes we can check Apache HTTP was indeed installed.

[ansible@FreeBSD-A ~]$ pkg info | grep apache

apache24-2.4.43 Version 2.4.x of Apache web server

[ansible@FreeBSD-A ~]$

By running the same playbook a second time we will check if Ansible makes further changes or it leaves the client nodes as they already are.

PLAY RECAP ********************************************************************************************************************************

freebsd-a : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

freebsd-b : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

As it can be seen in the ‘changed’ column, no modifications have been applied. That’s because the client nodes were already in the state the playbook demanded.

Playbooks can be extended to unthinkable levels once you start using the tool. They are a great solution for quickly deployments and maintain tens or hundreds of servers in good shape with relative ease and piece of mind. Down below a list of useful resources for those willing to dig deeper.

Tip. YAML files can be a bit annoying. Respect the chosen indentation at all times. The one you want or the one you find, but respect it. Otherwise… things may not work.

Resources

Ansible installation on FreeBSD

https://docs.ansible.com/ansible/latest/user_guide/intro_bsd.html

Playbook introduction.

https://docs.ansible.com/ansible/latest/user_guide/playbooks_intro.html

Working with Playbooks.

https://docs.ansible.com/ansible/latest/user_guide/playbooks.html

Playbook nomenclature.

https://docs.ansible.com/ansible/latest/reference_appendices/playbooks_keywords.html

Playbook modules.

https://docs.ansible.com/ansible/latest/modules/modules_by_category.html

Conclusions

I remember my days working the fourth largeest bank in Spain as an operator applying changes to configuration files and deploying Java applications left and right. We were all very careful at the CLI making sure we had typed everything correctly and following the instructions and steps one at a time, making sure everything had been executed correctly. Sometimes we did even make extra copies of some configuration files just in case the one who had written the steps had made a mistake. Script with loops were discouraged sometimes because when you have 48 instances of an application and you’ve messed it all, rolling back can be a pain, specially on long change operations. Ansible would have been a great tool to operate with. Only if…

This is all on this how to install Ansible on FreeBSD. The sky is the only limit. Go fly!

If you find the articles in Adminbyaccident.com useful to you, please consider making a donation.

Use this link to get $200 credit at DigitalOcean and support Adminbyaccident.com costs.

Get $100 credit for free at Vultr using this link and support Adminbyaccident.com costs.

Mind Vultr supports FreeBSD on their VPS offer.

 

 

 

Filed Under: FreeBSD, How To's

Recent Posts

  • How to install Redis for WordPress on FreeBSD
  • How to compile cloudflared in FreeBSD 13/14
  • How to configure FreeBSD to use a webcam (version 12 and 13)
  • Symbolic and Hard Links in UNIX and Linux
  • How to import iocage jails to Bastille on FreeBSD 13
  • How to load and unload kernel modules in Linux
  • How to use find in GNU/Linux and FreeBSD
  • How to install Mate on FreeBSD 12/13
  • How to install Nessus 10 on FreeBSD 12
  • How to enable TLS traffic from the origin server on Cloudflare Argo Tunnel
  • How to use Cloudflare’s Argo Tunnel service to publish a website on FreeBSD 12/13
  • How to setup MariaDB master-slave replication on FreeBSD
  • How to upload a FreeBSD custom image on DigitalOcean
  • How to install Drupal 9 on FreeBSD 13.0
  • How to manage site visitors based on IP Geolocation
  • How to enable Geolocation in AWStats on FreeBSD 13.0
  • How to install AWStats on FreeBSD 13.0
  • How to configure Modsecurity 3 for WordPress on FreeBSD
  • How to configure Apache HTTP with a TLS reverse proxy backend on FreeBSD
  • How to detect a WAF – Web Application Firewall

Archives

  • November 2024
  • October 2024
  • August 2023
  • July 2023
  • June 2023
  • May 2023
  • April 2023
  • February 2023
  • January 2023
  • December 2022
  • April 2022
  • March 2022
  • October 2021
  • September 2021
  • June 2021
  • May 2021
  • April 2021
  • March 2021
  • February 2021
  • January 2021
  • December 2020
  • July 2020
  • June 2020
  • May 2020
  • April 2020
  • March 2020
  • February 2020
  • January 2020
  • December 2019
  • November 2019
  • October 2019
  • August 2019
  • July 2019
  • June 2019
  • May 2019
  • April 2019
  • March 2019
  • February 2019
  • January 2019
  • September 2018
  • June 2018
  • May 2018
  • April 2018
  • February 2018
  • January 2018
  • November 2017
  • April 2017

RSS Admin… by accident!

  • How to install Redis for WordPress on FreeBSD
  • How to compile cloudflared in FreeBSD 13/14
  • How to configure FreeBSD to use a webcam (version 12 and 13)
  • Symbolic and Hard Links in UNIX and Linux
  • How to import iocage jails to Bastille on FreeBSD 13
  • How to load and unload kernel modules in Linux
  • How to use find in GNU/Linux and FreeBSD
  • How to install Mate on FreeBSD 12/13
  • How to install Nessus 10 on FreeBSD 12
  • How to enable TLS traffic from the origin server on Cloudflare Argo Tunnel

Copyright © 2025 · Magazine Pro Theme on Genesis Framework · WordPress · Log in