how to create Ansible playbook to obtain OS versions of the remote hosts?
Use one of the following Jinja2 expressions:
{{ hostvars[inventory_hostname].ansible_distribution }}
{{ hostvars[inventory_hostname].ansible_distribution_major_version }}
{{ hostvars[inventory_hostname].ansible_distribution_version }}
where:
hostvars
andansible_...
are built-in and automatically collected by Ansibleansible_distribution
is the host being processed by Ansible
For example, assuming you are running the Ansible role test_role
against the host host.example.com
running a CentOS 7 distribution:
---
- debug:
msg: "{{ hostvars[inventory_hostname].ansible_distribution }}"
- debug:
msg: "{{ hostvars[inventory_hostname].ansible_distribution_major_version }}"
- debug:
msg: "{{ hostvars[inventory_hostname].ansible_distribution_version }}"
will give you:
TASK [test_role : debug] *******************************************************
ok: [host.example.com] => {
"msg": "CentOS"
}
TASK [test_role : debug] *******************************************************
ok: [host.example.com] => {
"msg": "7"
}
TASK [test_role : debug] *******************************************************
ok: [host.example.com] => {
"msg": "7.5.1804"
}
Ansible playbook to install different packages depending on os version
Use a when
clause. Here's an example that will only run on ubuntu 12.04
when: "'{{ ansible_distribution}}' == 'Ubuntu' and '{{ ansible_distribution_release }}' == 'precise'"
You could alternatively use:
when: "'{{ ansible_distribution }}' == 'Ubuntu' and '{{ ansible_distribution_version }}': '12.04'"
Edit:
Later versions of Ansible (e.g. 2.7.1) would print a warning for this statement:
[WARNING]: when statements should not include jinja2 templating delimiters such as {{ }} or {% %}. Found: '{{ansible_distribution}}' == 'Ubuntu' and '{{ ansible_distribution_release }}' == 'bionic'
Ansible now expects another syntax for conditional statements, as stated in the docs.
For Ansible 2.5 you could try this:
when: "ansible_distribution|string == 'Ubuntu' and ansible_distribution_release|string == 'bionic'"
or even:
when:
- ansible_distribution|string == 'Ubuntu'
- ansible_distribution_release|string == 'bionic'
The latest version of the docs suggests to use access the ansible_facts like this:
when:
- ansible_facts['distribution'] == "CentOS"
- ansible_facts['distribution_major_version'] == "6"
How to get an arbitrary remote user's home directory in Ansible?
Ansible (from 1.4 onwards) already reveals environment variables for the user under the ansible_env
variable.
- hosts: all
tasks:
- name: debug through ansible.env
debug: var=ansible_env.HOME
Unfortunately you can apparently only use this to get environment variables for the connected user as this playbook and output shows:
- hosts: all
tasks:
- name: debug specified user's home dir through ansible.env
debug: var=ansible_env.HOME
become: true
become_user: "{{ user }}"
- name: debug specified user's home dir through lookup on env
debug: var=lookup('env','HOME')
become: true
become_user: "{{ user }}"
OUTPUT:
vagrant@Test-01:~$ ansible-playbook -i "inventory/vagrant" env_vars.yml -e "user=testuser"
PLAY [all] ********************************************************************
GATHERING FACTS ***************************************************************
ok: [192.168.0.30]
TASK: [debug specified user's home dir through ansible.env] *******************
ok: [192.168.0.30] => {
"var": {
"/home/vagrant": "/home/vagrant"
}
}
TASK: [debug specified user's home dir through lookup on env] *****************
ok: [192.168.0.30] => {
"var": {
"/home/vagrant": "/home/vagrant"
}
}
PLAY RECAP ********************************************************************
192.168.0.30 : ok=3 changed=0 unreachable=0 failed=0
As with anything in Ansible, if you can't get a module to give you what you want then you are always free to shell out (although this should be used sparingly as it may be fragile and will be less descriptive) using something like this:
- hosts: all
tasks:
- name: get user home directory
shell: >
getent passwd {{ user }} | awk -F: '{ print $6 }'
changed_when: false
register: user_home
- name: debug output
debug:
var: user_home.stdout
There may well be a cleaner way of doing this and I'm a little surprised that using become_user
to switch to the user specified doesn't seem to affect the env
lookup but this should give you what you want.
How to stop executing roles if the OS versions are different with in inventory
You can use the meta
option, end_play
, for example
- name: end play if not centos6
meta: end_play
when: ansible_distribution_version == "centos6"
More information in https://docs.ansible.com/ansible/latest/modules/meta_module.html
what you probably want to do is split your setup tasks into tasks/centos6.yml
and tasks/centos7.yml
and only include the relevant file in your playbook, for example
- name: setup centos7
include: tasks/centos7.yml
when: ansible_distribution_version == centos7
Related Topics
Can a Program Read Its Own Elf Section
How Does Ltrace (Library Tracing Tool) Work
How to Find Which Type of System Call Is Used by a Program
Linking a Static Library into a Shared Library
Cpu Utilization High for Sleeping Processes
Docker Create Two Bridges That Corrupts My Internet Access
How to Create a File Listener in Linux
Dynamic Listening Ports Inside Docker Container
Bridge Serial-Ports Over Network
Linux: Find a List of Files in a Dictionary Recursively
How to Launch Linux Subshell for Ssh_Askpass to Work in Linux
How to Create Ansible Playbook to Obtain Os Versions of The Remote Hosts