I'm a newbie in Ansible
, so I wrote a little ansible utility to install some package dependencies for a system I'm writing:
---
- hosts: all
user: root
tasks:
- name: install requirements
apt: name={{item}} state=latest update_cache=true
with_items:
- gcc
- python-dev
- python-setuptools
- python-software-properties
The current supported environments are Ubuntu
, Red Hat
and Mac OS X
. The current way this playbook is written it will only work in Ubuntu (Debian)
. How can I have that part of the code be executed according to the OS? For Ubuntu
it's apt
, for Red Hat
it's yum
and for Mac OS X
brew
.
Using the Ansible playbook The gather_facts module from the Ansible playbook runs the setup module by default at the start of each playbook to gather the facts about remote hosts. Fetch the Ansible facts and display them using a playbook.
You can use the environment keyword at the play, block, or task level to set an environment variable for an action on a remote host. With this keyword, you can enable using a proxy for a task that does http requests, set the required environment variables for language-specific version managers, and more.
In an Ansible playbook, when local_action is used, Ansible will run the module work mentioned under it on the controller node. Mostly modules used with local_action are shell and command. As you can do almost all the tasks using these modules on the controller node.
It is convenient to use in an heterogeneous environment of machines without having to create a specific task for each package manager. package calls behind the module for the package manager used by the operating system discovered by the module ansible.builtin.setup. If setup was not yet run, package will run it.
The first step to assure Ansible can talk to the z/OS managed node, is to setup the system information inside either the inventory file or hosts file. The default location for hosts file is /etc/ansible/hosts.
For instance, if you're going to write your Ansible instructions (a "playbook," as it's called in Ansible) on a laptop running Fedora, start with the dnf module. If you're writing on Elementary OS, use the apt module, and so on.
The return value of the task will be a non-zero value if Apache is not installed on the host. Usually, Ansible would stop executing other tasks because of this non-zero value, but the failed_when: no gives Ansible permission to continue with the next set of tasks when it encounters a non-zero value.
The normal approach to this is to have an OS family specific task file that is conditionally included by checking the ansible_os_family
fact.
So you may have a main.yml
task file in your role that looks something like:
# Arbitrary task here, not needed but the point is you can have any generic tasks directly in main.yml
- name: get the date
shell: `date`
register: date
- include: debian.yml
when: ansible_os_family == 'Debian'
- include: redhat.yml
when: ansible_os_family == 'RedHat'
And then in debian.yml
we have:
- name: install requirements
apt: name={{item}} state=latest update_cache=true
with_items:
- gcc
- python-dev
- python-setuptools
- python-software-properties
and in redhat.yml
we have:
- name: install requirements
yum: name={{item}} state=latest update_cache=true
with_items:
- gcc
- python-dev
- python-setuptools
- python-software-properties
Obviously this allows you to set different dependency lists depending on the OS family as well.
If you wanted to you could also conditionally include OS family (or really anything you can check a fact for) specific vars like this:
- name: Include OS-specific variables.
include_vars: "{{ item }}"
with_first_found:
- ../vars/{{ ansible_distribution | lower }}.yml
- ../vars/{{ ansible_os_family | lower }}.yml
And then set your dependency lists in say vars/debian.yml
like this:
python_dependencies:
- gcc
- python-dev
- python-setuptools
- python-software-properties
so now your tasks/debian.yml
looks like:
- name: install requirements
apt: name={{item}} state=latest update_cache=true
with_items: python_dependencies
You can see a list of the OS's and their families by checking the source code here which has this dict of all the OS families:
# A list with OS Family members
OS_FAMILY = dict(
RedHat = 'RedHat', Fedora = 'RedHat', CentOS = 'RedHat', Scientific = 'RedHat',
SLC = 'RedHat', Ascendos = 'RedHat', CloudLinux = 'RedHat', PSBM = 'RedHat',
OracleLinux = 'RedHat', OVS = 'RedHat', OEL = 'RedHat', Amazon = 'RedHat',
XenServer = 'RedHat', Ubuntu = 'Debian', Debian = 'Debian', Raspbian = 'Debian', Slackware = 'Slackware', SLES = 'Suse',
SLED = 'Suse', openSUSE = 'Suse', SuSE = 'Suse', SLES_SAP = 'Suse', Gentoo = 'Gentoo', Funtoo = 'Gentoo',
Archlinux = 'Archlinux', Manjaro = 'Archlinux', Mandriva = 'Mandrake', Mandrake = 'Mandrake',
Solaris = 'Solaris', Nexenta = 'Solaris', OmniOS = 'Solaris', OpenIndiana = 'Solaris',
SmartOS = 'Solaris', AIX = 'AIX', Alpine = 'Alpine', MacOSX = 'Darwin',
FreeBSD = 'FreeBSD', HPUX = 'HP-UX'
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With