How to Create Ansible Playbook to Obtain Os Versions of The Remote Hosts

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 and ansible_... are built-in and automatically collected by Ansible
  • ansible_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



Leave a reply



Submit