0

I wrote the playbook to apply the security patches on Linux servers, the only part remaining is to write the task to restart the patched server.

Below is the content of the task to apply the patches

- name: Deploying Security Packages                              
  shell: "yum update --security -y"                              
  register: progress                                             
  when: deploypackages == "y"                                    
                                                                 
- name: Installed Packages                                       
  debug:                                                         
    msg: "{{ progress.stdout_lines | regex_search('complete') }}"
  #when: progress.changed | regex_search('complete')   

I was looking for a filter to look in the output for the word in registered variable, if it is completed and kernel and then reboot the server.

Thanks

Attempt 1 - Failed

For testing purpose I've changed kernel with xz-libs, but it is failing when reaches the when condition.

---
- name: Deploying Security Packages
  #shell: "yum update --security -y"
  yum:
    name: '*'
    state: latest
    security: yes
  register: yum_update
  when: deploypackages == "y"

- name: Installed Packages
  debug:
    msg: " Packages installed Successfully "
  when:
    - yum_update.changed
    - yum_update.stdout | regex_search('xz-libs', ignorecase=True ) is not none

It gives this error

TASK [deploying_security_updates : Deploying Security Packages] **********************
changed: [192.168.8.26]

    TASK [deploying_security_updates : Installed Packages] *******************************
    fatal: [192.168.8.26]: FAILED! => {"msg": "The conditional check 'yum_update.stdout | regex_search('*xz-libs*', ignorecase=True ) is not none' failed. The error was: nothing to repeat\n\nThe error appears to be in '/home/sysadmin/ansible_files/play-security-update/roles/deploying_security_updates/tasks/main.yaml': line 11, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: Installed Packages\n  ^ here\n"}

Debug

- name: Deploying Security Packages                                                
  yum:                                                                             
    name: '*'                                                                      
    state: latest                                                                  
    security: yes                                                                  
  register: yum_update                                                             
  when: deploypackages == "y"                                                      
                                                                                   
- name: Installed Packages                                                         
  debug:                                                                           
    #msg: " Packages installed Successfully "                                      
    msg: " {{ yum_update.stdout | regex_search('xz-libs', ignorecase=True ) }}"    
  #when:                                                                           
  #  - yum_update.changed                                                          
  #  - yum_update.stdout | regex_search('*xz-libs*', ignorecase=True ) is not none 



Do you want to deploy Packages: y

PLAY [To Apply Security Patches on Linux Servers] *******************************************************************************************************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************************************************************************************************************************************
ok: [192.168.8.26]

TASK [Condition Failed! Wrong User Input] ***************************************************************************************************************************************************************************************************
skipping: [192.168.8.26]

TASK [check_for_updates : Looking for Package Updates] **************************************************************************************************************************************************************************************
skipping: [192.168.8.26]

TASK [check_for_updates : Printing Available Updates] ***************************************************************************************************************************************************************************************
skipping: [192.168.8.26]

TASK [deploying_security_updates : Deploying Security Packages] *****************************************************************************************************************************************************************************
changed: [192.168.8.26]

TASK [deploying_security_updates : Installed Packages] **************************************************************************************************************************************************************************************
fatal: [192.168.8.26]: FAILED! => {"msg": "Unexpected templating type error occurred on ( {{ yum_update.stdout | regex_search('xz-libs', ignorecase=True ) }}): expected string or buffer"}

PLAY RECAP **********************************************************************************************************************************************************************************************************************************
192.168.8.26               : ok=2    changed=1    unreachable=0    failed=1    skipped=3    rescued=0    ignored=0

Debug Output

ok: [192.168.8.26] => {
    "msg": {
        "changed": true,
        "changes": {
            "installed": [],
            "updated": [
                [
                    "xz",
                    "5.2.2-2.el7_9.x86_64 from rhel-remote"
                ],
                [
                    "xz-libs",
                    "5.2.2-2.el7_9.x86_64 from rhel-remote"
                ]
            ]
        },
        "failed": false,
        "msg": "",
        "rc": 0,
        "results": [
            "Loaded plugins: langpacks, product-id, search-disabled-repos, subscription-\n              : manager\nThis system is not registered with an entitlement server. You can use subscription-manager to register.\n --> device-mapper-persistent-data-0.7.3-3.el7.x86_64 from @anaconda/7.6 removed (updateinfo)\n --> 7:device-mapper-event-1.02.170-6.el7_9.5.x86_64 from rhel-remote removed (updateinfo)\n --> libgnomekbd-3.26.0-3.el7.x86_64 from rhel-remote removed (updateinfo)\n --> cryptsetup-python-2.0.3-3.el7.x86_64 from @anaconda/7.6 removed (updateinfo)\n --> PackageKit-gstreamer-plugin-1.1.10-2.el7.x86_64 from rhel-remote removed (updateinfo)\n --> libstoragemgmt-1.6.2-4.el7.x86_64 from @anaconda/7.6 removed (updateinfo)\n --> PackageKit-gtk3-module-1.1.10-2.el7.x86_64 from rhel-remote removed (updateinfo)\n --> 7:device-mapper-event-1.02.149-8.el7.x86_64 from @anaconda/7.6 removed (updateinfo)\n --> setroubleshoot-plugins-3.0.67-3.el7.noarch from @anaconda/7.6 removed (updateinfo)\n --> libdrm-2.4.91-3.el7.x86_64 from @anaconda/7.6 removed (updateinfo)\n --> mesa-dri-drivers-18.3.4-12.el7_9.x86_64 from rhel-remote removed (updateinfo)\n --> subscription-manager-plugin-container-1.24.51-1.el7_9.x86_64 from rhel-remote removed (updateinfo)\n --> firewalld-0.6.3-13.el7_9.noarch from rhel-remote removed (updateinfo)\n --> gdb-7.6.1-114.el7.x86_64 from @anaconda/7.6 removed (updateinfo)\n --> grubby-8.28-26.el7.x86_64 from rhel-remote removed (updateinfo)\n --> hostname-3.13-3.el7.x86_64 from @anaconda/7.6 removed (updateinfo)\n --> 32:bind-libs-lite-9.11.4-26.P2.el7_9.9.x86_64 from rhel-remote removed (updateinfo)\n --> abrt-dbus-2.1.11-52.el7.x86_64 from @anaconda/7.6 removed (updateinfo)\n --> unzip-6.0-21.el7.x86_64 from @rhel-remote removed (updateinfo)\n
 Package xz-libs.x86_64 0:5.2.2-2.el7_9 will be an update\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package         Arch           Version               Repository           Size\n================================================================================\nUpdating:\n xz              x86_64         5.2.2-2.el7_9         rhel-remote         229 k\n xz-libs         x86_64         5.2.2-2.el7_9         rhel-remote         103 k\n\nTransaction Summary\n================================================================================\nUpgrade  2 Packages\n\nTotal download size: 332 k\nDownloading packages:\nNo Presto metadata available for rhel-remote\n--------------------------------------------------------------------------------\nTotal                                              1.3 MB/s | 332 kB  00:00     \nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Updating   : xz-libs-5.2.2-2.el7_9.x86_64                                 1/4 \n  Updating   : xz-5.2.2-2.el7_9.x86_64                                      2/4 \n  Cleanup    : xz-5.2.2-1.el7.x86_64                                        3/4 \n  Cleanup    : xz-libs-5.2.2-1.el7.x86_64                                   4/4 \n  Verifying  : xz-libs-5.2.2-2.el7_9.x86_64                                 1/4 \n  Verifying  : xz-5.2.2-2.el7_9.x86_64                                      2/4 \n  Verifying  : xz-libs-5.2.2-1.el7.x86_64                                   3/4 \n  Verifying  : xz-5.2.2-1.el7.x86_64                                        4/4 \n\nUpdated:\n  xz.x86_64 0:5.2.2-2.el7_9            xz-libs.x86_64 0:5.2.2-2.el7_9           \n\nComplete!\n"
        ]
    }
}

PLAY RECAP **********************************************************************************************************************************************************************************************************************************
192.168.8.26               : ok=3    changed=1    unreachable=0    failed=0    skipped=3    rescued=0    ignored=0
4
  • 2
    Why are you not using the yum module? Using shell makes it way harder to parse output and to create idempotence.
    – Panki
    Jun 23 at 7:21
  • I used yum module, but it doesn't do anything. Even though there are secuirty packages. i used "yum: \ state: latest\ security: yes"
    – OmiPenguin
    Jun 23 at 8:46
  • And why would it? Read the docs. You are not naming any packages state: latest could apply to.
    – Panki
    Jun 23 at 8:53
  • yes i missed the name: '*' part , now it does install. Now can you help me with original question ?
    – OmiPenguin
    Jun 23 at 8:55

2 Answers 2

1

Please take note that a restart may be required not only after installing a new kernel but also after updates of microcode, glibc, SSL libs, etc.. So some more events will require a restart and needs to be checked too.

In RHEL there are utilities based around the native OS package manager available, in example yum-utils which contains a needs-restarting script to query if it would be necessary to do so after applying updates.

Example (based on RHEL 7)

After resolving the dependencies

- name: Install basic admin tools
  yum:
    name: yum-utils
    state: latest

checks are simple as

- name: Check if reboot_required
  shell:
    cmd: "needs-restarting -r"
  changed_when: false
  failed_when: reboot_required.rc != 0 and reboot_required.rc != 1
  check_mode: false
  register: reboot_required

- name: Report reboot_required
  debug:
    msg: "{{  reboot_required.rc | bool }} "
  changed_when: reboot_required.rc == 1
  check_mode: false

and resulting into an output of

TASK [Report reboot_required] **************************************************
ok: [test1.example.com] => {
    "msg": "True "
}
ok: [test2.example.com] => {
    "msg": "False "
}

Packages for checking if a restart is required are also available for other distributions.

Similar Q&A


Additionally and depending on the infrastructure and environement, one could left the reboot fully automated to the system in example via cronjobs like

# Reboot cron job
# /etc/cron.d/

# mm hh dom mon dow user command
  59  0   *   *   * root needs-restarting -r || /usr/sbin/shutdown --no-wall -r +1
0

To check if the task is completed and the word kernel in the output has been mentioned you would get the following task:

- name: "Deploying Security Packages"
  ansible.builtin.yum:
    name: '*'
    security: yes
    state: latest
  register: yum_update

- name: "Just debug for now"
  ansible.builtin.debug:
    msg: "This should be a reboot"
  when:
    - yum_update.changed
    - (yum_update.results[0] | regex_search('kernel')) is not none

The two - with the when means a logical AND so the update should be changed and thus completed, otherwise it would fail, and in the output of the stdout there should be the word matching kernel. If the word is not there the check will output a none according the documentation.

10
  • It failed, Description added under "Attempt 1 - Failed" in Question
    – OmiPenguin
    Jun 23 at 11:33
  • Could you try to just use the debug on the regex line like so: msg: "{{ yum_update.stdout | regex_search('xz-libs', ignorecase=True ) }}" without a when, just print what it returns?
    – Mr. Diba
    Jun 23 at 12:59
  • Hello @Mr, Diba, i updated the task and enabled the debug , tasks and run is in question below Debug heading
    – OmiPenguin
    Jun 27 at 7:06
  • Now I'm curious what msg: "{{ yum_update }}" actually holds?
    – Mr. Diba
    Jun 28 at 10:45
  • 1
    Well it could be because results is a dictionary, could you try: yum_update.results[0]?
    – Mr. Diba
    Jun 28 at 11:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.