Table of contents
1.
Introduction
2.
Connecting to BSD Nodes
3.
Bootstrapping BSD
4.
Setting the Python Interpreter
4.1.
FreeBSD Packages and Ports
4.2.
INTERPRETER_PYTHON_FALLBACK
4.3.
Debug the Discovery of Python
5.
Frequently Asked Questions
5.1.
What is DevOps?
5.2.
What is Ansible?
5.3.
What is Puppet?
5.4.
What is Ansible Unarchive?
5.5.
What is Ansible Playbook?
6.
Conclusion
Last Updated: Mar 27, 2024
Easy

Ansible and BSD

Author Rajat Agrawal
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

Ansible is a Red Hat-sponsored open-source community project that offers the simplest method to automate IT. Ansible is the only automation language that can be utilized by entire IT teams, from system administrators to network administrators to developers and managers.

Ansible

Management of BSD machines differs from the management of other Unix-like machines.

Connecting to BSD Nodes

BSD Nodes

By default, Ansible connects to managed nodes through OpenSSH. If you use SSH keys for authentication, this works on BSD. If you use SSH passwords for authentication, Ansible will utilize sshpass. Because most versions of sshpass do not handle BSD login prompts properly, use paramiko instead of OpenSSH when utilizing SSH passwords against BSD workstations. This can be done globally in ansible.cfg or as an inventory/group/host setting. For example:

mybsdhost1 ansible_connection=paramiko
You can also try this code with Online Python Compiler
Run Code

Bootstrapping BSD

Bootstrap BSD

Ansible is agentless by default, but on managed nodes, it needs Python. Without Python, just the raw module will function. The use of Python is necessary to fully utilize Ansible's features, even if this module can be used to install Python and bootstrap Ansible on BSD versions (see below).

The installation of Python that comes with the JSON library needed for full Ansible functioning is demonstrated in the example below. For the majority of FreeBSD versions, you can run the following commands on your control machine:

ansible -m raw -a "pkg install -y python" mybsdhost1
You can also try this code with Online Python Compiler
Run Code


Or for OpenBSD:

ansible -m raw -a "pkg_add python%3.8"
You can also try this code with Online Python Compiler
Run Code


After doing this, you can utilize Ansible modules other than the raw module.

Setting the Python Interpreter

Interpreter

Ansible can't always rely on the current environment or env variables to get the right Python binary because it needs to support various Unix-like operating systems and distributions. Modules by default point to /usr/bin/python since this is the most frequent location. This path could be different on BSD variations; therefore, it's a good idea to let Ansible know where the binary is. Look at INTERPRETER_PYTHON. Set the ansible_python_interpreter inventory variable, for instance:

[freebsd:vars]
ansible_python_interpreter=/usr/local/bin/python
[openbsd:vars]
ansible_python_interpreter=/usr/local/bin/python3.8
You can also try this code with Online Python Compiler
Run Code

FreeBSD Packages and Ports

The default installation of the /usr/local/bin/python executable file or a link to an executable file is not guaranteed on FreeBSD. Installing at least the Python versions that Ansible supports, such as lang/python38, as well as both meta ports lang/python3 and lang/python, is recommended for remote hosts when using Ansible. 

From /usr/ports/lang/python3/pkg-descr:

This is a meta port to the Python 3.x interpreter that offers symbolic links to bin/python3, bin/pydoc3, bin/idle3, and other Python modules to provide compatibility with scripts written in any minor version.

From /usr/ports/lang/python/pkg-descr:

This meta port for the Python interpreter offers symbolic links to bin/python, bin/pydoc, bin/idle, and other bin directories to provide compatibility with Python scripts of all versions.

The following packages need to be installed:

shell> pkg info | grep python
python-3.8_3,2                 "meta-port" for the default version of Python interpreter
python3-3_3                    Meta-port for the Python interpreter 3.x
python38-3.8.12_1              Interpreted object-oriented programming language
You can also try this code with Online Python Compiler
Run Code


and the following executables and links

shell> ll /usr/local/bin/ | grep python
lrwxr-xr-x  1 root  wheel       7 Jan 25 09:30 python@ -> python3
lrwxr-xr-x  1 root  wheel      14 Jan 25 09:30 python-config@ -> python3-config
lrwxr-xr-x  1 root  wheel       9 Jan 25 09:29 python3@ -> python3.8
lrwxr-xr-x  1 root  wheel      16 Jan 25 09:29 python3-config@ -> python3.8-config
-r-xr-xr-x  1 root  wheel    5248 Jan 14 00:12 python3.8*
-r-xr-xr-x  1 root  wheel    3153 Jan 14 00:12 python3.8-config*
You can also try this code with Online Python Compiler
Run Code

INTERPRETER_PYTHON_FALLBACK

Ansible offers a helpful option ansible_interpreter_python_fallback since version 2.8 allows users to provide a list of paths to look in for Python. INTERPRETER_PYTHON_FALLBACK is described. The first item discovered after searching this list will be utilized. For instance, the setup shown below would render unnecessary the installation of the Python meta-ports in the previous section, as the first two items in the list will be bypassed and /usr/local/bin/python3.8 will be found.

ansible_interpreter_python_fallback=['/usr/local/bin/python', '/usr/local/bin/python3', '/usr/local/bin/python3.8']
You can also try this code with Online Python Compiler
Run Code


You can use this variable, which was added by earlier Python versions, and add it, for instance, to the group vars/all. Afterward, if necessary, override it for particular groups in group vars/"group1, group2,..." and for particular hosts in host vars/"host1, host2,..."

Debug the Discovery of Python

For example, given the inventory:

shell> cat hosts
[test]
test_11
test_12
test_13

[test:vars]
ansible_connection=ssh
ansible_user=admin
ansible_become=yes
ansible_become_user=root
ansible_become_method=sudo
ansible_interpreter_python_fallback=['/usr/local/bin/python', '/usr/local/bin/python3', '/usr/local/bin/python3.8']
ansible_perl_interpreter=/usr/local/bin/perl
You can also try this code with Online Python Compiler
Run Code


The playbook below:

shell> cat playbook.yml
- hosts: test_11
  gather_facts: false
  tasks:
    - command: which python
      register: result
    - debug:
        var: result.stdout
    - debug:
        msg: |-
          {% for i in _vars %}
          {{ i }}:
            {{ lookup('vars', i)|to_nice_yaml|indent(2) }}
          {% endfor %}
      vars:
        _vars: "{{ query('varnames', '.*python.*') }}"
You can also try this code with Online Python Compiler
Run Code


Displays the details:

shell> ansible-playbook -i hosts playbook.yml

PLAY [test_11] *******************

TASK [command] *******************
[WARNING]: Platform freebsd on host test_11 is using the discovered Python interpreter at
/usr/local/bin/python, but future installation of another Python interpreter could change the
meaning of that path. See https://docs.ansible.com/ansible-
core/2.12/reference_appendices/interpreter_discovery.html for more information.
changed: [test_11]

TASK [debug] ************************
ok: [test_11] =>
  result.stdout: /usr/local/bin/python
TASK [debug] ************************
ok: [test_11] =>
  msg: |-
    ansible_interpreter_python_fallback:
      - /usr/local/bin/python
      - /usr/local/bin/python3
      - /usr/local/bin/python3.8

    discovered_interpreter_python:
      /usr/local/bin/python

    ansible_playbook_python:
      /usr/bin/python3
You can also try this code with Online Python Compiler
Run Code


You can see that the FreeBSD remote host found the first item in the list ansible_interpreter_python_fallback. The path to Python on the Linux controller that executed the playbook is stored in the variable ansible_playbook_python.

Because this is what you actually want when using /usr/local/bin/python ("interpreters installed later may change which one is used"), you can either disregard it or remove the warning by setting the variable ansible_python_interpreter=auto_silent. For instance

shell> cat hosts
[test]
test_11
test_12
test_13

[test:vars]
ansible_connection=ssh
ansible_user=admin
ansible_become=yes
ansible_become_user=root
ansible_become_method=sudo
ansible_interpreter_python_fallback=['/usr/local/bin/python, '/usr/local/bin/python3', '/usr/local/bin/python3.8']
ansible_python_interpreter=auto_silent
ansible_perl_interpreter=/usr/local/bin/perl
You can also try this code with Online Python Compiler
Run Code

 

Also see, How to Check Python Version in CMD

Frequently Asked Questions

What is DevOps?

DevOps is a collection of cultural ideas, operational procedures, and technical resources that enhances an organization's ability to provide products and services rapidly.

What is Ansible?

Ansible is an open-source IT engine that automates the deployment of IT technologies, including intra-service orchestration, cloud provisioning, and application deployment.

What is Puppet?

Puppet is a server configuration management program that may be used to configure, deploy, and manage servers.

What is Ansible Unarchive?

The Ansible unarchive module is used to unpack or uncompress files from archive files like zip, tar, and tar.gz. Before uncompressing the files, it might optionally transfer the files to a remote server before uncompressing them.

What is Ansible Playbook?

Playbooks are the files in which the Ansible code is written. Playbooks are written in YAML format. YAML stands for "Yet Another Markup Language" thus, there isn't much syntax required.

Conclusion

In this article, we have extensively discussed Ansible and BSD, how to connect to the BSD node, and how to bootstrap BSD. If you want to learn more, check out our articles on Ansibe vs. ChefAnsible vs. PuppetConstruct the Full K-ary Tree from its Preorder TraversalRegular and Bipartite graphs, and Planar and Non-Planar Graphs.

Happy Coding!

Live masterclass