Need to check whether you need to reboot for a kernel update?

You could reliably determine the latest installed kernel version via the following rpm query:

rpm -q kernel --queryformat '%{installtime} %{version}-%{release}.%{arch}\n' | sort -n -k1 | tail -1 | cut -d ' ' -f 2

Sample output on RHEL 7:

3.10.0-229.11.1.el7.x86_64

Now just check whether the output of uname -r matches:

3.10.0-229.1.2.el7.x86_64

In this example, it does not match and a reboot is required.

You could use test to compare the strings:

if [ "`rpm -q kernel --queryformat '%{installtime} %{version}-%{release}.%{arch}\n' | sort -n -k1 | tail -1 | cut -d ' ' -f 2`" = "`uname -r`" ]; then echo "latest kernel already booted."; else echo "new kernel. reboot required."; fi

Answer for 2021

As @kawing-chiu mentioned in their answer, dnf now has a needs-restarting module which does just what the question requires. It determines if system packages have been updated since last boot, although that is not limited to only kernel changes. This behavior is arguably better than simply comparing kernel version with installed packages.

The needs-restarting dnf module is not accessible through the ansible.builtin.dnf Ansible module, but it can be called through ansible.builtin.shell or ansible.builtin.command by its alias needs-restarting -r, more directly with dnf needs-restarting -r, or even more explicitly with /usr/bin/dnf needs-restarting -r.

The -r flag does not seem to require root privileges and simply reports if a reboot is necessary. The return code is 0 if no reboot is necessary and 1 if it is. Therefore, we should be able to use a task such as this one, which is adapted from the one suggested by Joël Cattin:

- name: Check if a reboot is required
  ansible.builtin.command: needs-restarting -r
  register: reg_reboot_required
  ignore_errors: yes
  failed_when: false
  changed_when: reg_reboot_required.rc != 0
  notify:
    - Reboot server 

You will also need a handler named, or listening to, Reboot server to carry out the reboot task. Something like this will do the trick:

- name : Reboot server
  ansible.builtin.reboot:
    msg: "Reboot initiated by Ansible after OS update"
    reboot_timeout: 3600
    test_command: uptime

I hope this answer helps anyone who comes along seeking a solution to this problem.