19

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.

tlo
  • 1,571
  • 1
  • 25
  • 38
AmigoSe
  • 366
  • 1
  • 2
  • 13
  • `gather_facts: True` is required for most of the answers on this page to work. – ishigoya Jul 31 '20 at 01:41
  • Checkout this link https://stackoverflow.com/questions/61460151/ansible-not-reporting-distribution-info-on-ubuntu-20-04/70754268#70754268 – user3710949 Jan 18 '22 at 10:55

6 Answers6

27

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"
}
Gabriel Petrovay
  • 20,476
  • 22
  • 97
  • 168
4

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:.

Frock81
  • 111
  • 1
  • 4
2

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"
Matthias Bloch
  • 303
  • 3
  • 6
1

For a couple of windows instances:

    - debug:
        msg:
        - "ansible_distribution {{ hostvars[inventory_hostname].ansible_distribution }}"
        - "major version {{ hostvars[inventory_hostname].ansible_distribution_major_version }}"
        - "version {{ hostvars[inventory_hostname].ansible_distribution_version }}"

gives:

ok: [server1] => {
"msg": [
    "ansible_distribution Microsoft Windows Server 2008 R2 Standard ",
    "major version 6",
    "version 6.1.7601.65536"
]

}

ok: [server2] => {
"msg": [
    "ansible_distribution Microsoft Windows Server 2016 Standard",
    "major version 10",
    "version 10.0.14393.0"
]

}

Straff
  • 5,499
  • 4
  • 33
  • 31
0

"AWS does not provide this feature " - you can check file /etc/os-release to get details of aws instance.

For example

[ec2-user@ip-xx-xx-xx ~]$ cat /etc/os-release
NAME="Amazon Linux AMI"
VERSION="2016.03"
ID="amzn"
ID_LIKE="rhel fedora"
VERSION_ID="2016.03"
PRETTY_NAME="Amazon Linux AMI 2016.03"
ANSI_COLOR="0;33"
CPE_NAME="cpe:/o:amazon:linux:2016.03:ga"
HOME_URL="http://aws.amazon.com/amazon-linux-ami/"
Vor
  • 33,215
  • 43
  • 135
  • 193
  • Thanks Vor for the response however, if i were to login to 450 redhat servers and cat /etc/redhat-release .. i will most likely go nuts in couple of hours.... That was the reason why i wanted to use ansible to automate this. Any Ansible experts here? – AmigoSe Jun 29 '16 at 01:27
  • you would also need to use debug to print the stdout from your `cat` command – MillerGeek Jun 29 '16 at 20:00
0
- name: obtain OS version
  shell: Redhat-release
  register: result

- name: print OS version
  debug: var=result.stdout
MillerGeek
  • 3,057
  • 20
  • 23
  • 1
    Thanks smiller171 I tried the following tasks: - name: Collect OS version of Remote host shell: cat /etc/redhat-release - name: Pring OS Version debug: var=result.stdout TASK [Print OS Version] ******************************************************** ok: [IP] => { "result.stdout": "VARIABLE IS NOT DEFINED!" Var isnot defined came up – AmigoSe Jun 30 '16 at 20:32
  • look at my example again. registering the result of your shell command is important. – MillerGeek Jul 01 '16 at 14:29