Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to create Ansible playbook to obtain OS versions of the remote hosts?

I'm new to ansible. I have a requirement that requires me to pull OS version for of more than 450 linux severs hosted in AWS. AWS does not provide this feature - it rather suggests us to get it from puppet or chef.

I created few simple playbooks which does not run

---
- hosts: testmachine
user: ec2-user
sudo: yes
tasks:
- name: Update all packages to latest
yum: name=* state=latest

task:
- name: obtain OS version
shell: Redhat-release

playbook should output a text file with hostname and OS version. Any insight on this will be highly appreciated.

like image 990
AmigoSe Avatar asked Jun 28 '16 13:06

AmigoSe


People also ask

Can Ansible manage Windows hosts?

Can Ansible run on Windows?  No, Ansible can only manage Windows hosts. Ansible cannot run on a Windows host natively, though it can run under the Windows Subsystem for Linux (WSL).

Which command would you use to get the hostname of a remote host with Ansible?

ansible_hostname takes the uname -n or the hostname command output of the remote machine.

How do you access the environment variables of target remote hosts in Ansible?

Accessing the variables The environment variables of the remote servers can be accessed via 'facts'. There is a sublist called 'ansible_env' which has all the env variables inside it. Note that, the fact-gathering needs to be 'ON' if you want to access this. By default, it is set to true.

What happens when Ansible runs a playbook?

Every time, ansible runs a playbook, it checks for the listed hosts in the host’s file and fetches the available information against those hosts, then use this information to make connection, login and execute tasks on remote hosts. What is Ansible Hosts File?

What is a hostname in Ansible playbook?

A hostname or inventory group is specified at the beginning of the playbook and defines the hosts on which Ansible will run the playbook. Our playbook will contain three plays to handle each type of host I identified in the requirements statement.

How do I run Ansible commands against specific hosts?

When you execute Ansible through an ad hoc command or by running a playbook, you must choose which managed nodes or groups you want to execute against. Patterns let you run commands and playbooks against specific hosts and/or groups in your inventory.

How does Ansible_env work with remote users?

Ansible populates ansible_env values by gathering facts, so the value of the variables depends on the remote_user or become_user Ansible used when gathering those facts. If you change remote_user/become_user the values in ansible-env may not be the ones you expect.


3 Answers

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"
}
like image 129
4 revs, 2 users 76% Avatar answered Oct 23 '22 08:10

4 revs, 2 users 76%


In a structured way:

- hosts: all
  become: no
  vars:
    output_file: os.csv
  tasks:
    - block:
        # For permisison setup.
        - name: get current user
          command: whoami
          register: whoami
          run_once: yes

        - name: clean file
          copy:
            dest: "{{ output_file }}"
            content: 'hostname,distribution,version,release'
            owner: "{{ whoami.stdout }}"
          run_once: yes

        - name: fill os information
          lineinfile:
            path: "{{ output_file }}"
            line: "{{ ansible_hostname }},\
              {{ ansible_distribution }},\
              {{ ansible_distribution_version }},\
              {{ ansible_distribution_release }}"
          # Tries to prevent concurrent writes.
          throttle: 1
      delegate_to: localhost

Creates a comma separated file named os.csv in execution folder. You can use any variables you want editing line:.

like image 44
Frock81 Avatar answered Oct 23 '22 10:10

Frock81


Ansible already provides a lot of information about the remote host in the "hostvars" variable that is automatically available.

To see information of your host named "my_remote_box_name", e.g. do

- debug: var=hostvars['my_remote_box_name']

Some OS information is in

hostvars['my_remote_box_name']['ansible_lsb']

Which, for one of my ubuntu hosts would be along:

{
  "hostvars['my_remote_box_name']['ansible_lsb']": {
    "codename": "xenial", 
    "description": "Ubuntu 16.04.1 LTS", 
    "id": "Ubuntu", 
    "major_release": "16", 
    "release": "16.04"
}

You can just use those variables in your playbooks and templates, using the "{{ variable_name }}" notation.

- debug: msg="My release is {{ansible_lsb.release}}"

output:

"msg": "My release is 16.04"
like image 24
Matthias Bloch Avatar answered Oct 23 '22 08:10

Matthias Bloch