{"id":1563,"date":"2016-09-20T10:00:58","date_gmt":"2016-09-20T08:00:58","guid":{"rendered":"https:\/\/www.my-it-brain.de\/wordpress\/?p=1563"},"modified":"2021-01-25T13:03:27","modified_gmt":"2021-01-25T12:03:27","slug":"ansible-patch-management-fuer-red-hat-systeme","status":"publish","type":"post","link":"https:\/\/www.my-it-brain.de\/wordpress\/ansible-patch-management-fuer-red-hat-systeme\/","title":{"rendered":"Ansible: Patch-Management f\u00fcr Red Hat Systeme"},"content":{"rendered":"\n<p>Als Linux-Distribution f\u00fcr den Betrieb im Rechenzentrum fiel unsere Wahl vor einiger Zeit auf Red Hat Enterprise Linux. Zu meinen Aufgaben geh\u00f6rt es, ein Patch-Management f\u00fcr diese Systeme zu entwickeln, welches die folgenden Anforderungen erf\u00fcllt:<\/p>\n<ol>\n<li>Die zu aktualisierenden Hosts werden in Gruppen im Ansible Inventory verwaltet. Eine Gruppe entspricht dabei einer Stage\/Phase f\u00fcr das Patch-Management.<\/li>\n<li>An definierten Stichtagen sollen automatisiert fehlende Sicherheitsaktualisierungen auf den Systemen in den verschiedenen Stages\/Phasen eingespielt werden k\u00f6nnen.<\/li>\n<li>Dabei sollen ausschlie\u00dflich Pakete aktualisiert werden, f\u00fcr die Red Hat Security Advisory ver\u00f6ffentlicht wurden.<\/li>\n<li>Wenn Pakete aktualisiert wurden, soll der Host anschlie\u00dfend neugestartet werden.<\/li>\n<\/ol>\n<p>Ich habe mich entschieden, diese Anforderungen durch die Verwendung von Ansible zu erf\u00fcllen. Wem Ansible noch kein Begriff ist, m\u00f6ge einen Blick in die Quellen am Ende des Artikels werfen.[1. <a href=\"https:\/\/www.my-it-brain.de\/wordpress\/ansible-it-automation-fuer-jedermann\/\">Ansible &#8211; IT-Automation f\u00fcr Jedermann<\/a>] [2. <a href=\"https:\/\/docs.ansible.com\/ansible\/2.9\/user_guide\/index.html\" target=\"_blank\" rel=\"noopener noreferrer\">Ansible Documentation {en}<\/a>] [3. <a href=\"https:\/\/www.my-it-brain.de\/wordpress\/linux-benutzerkonten-mit-ansible-verwalten\/\">Linux-Benutzerkonten mit Ansible verwalten<\/a>] [4. <a href=\"https:\/\/www.my-it-brain.de\/wordpress\/ansible-das-modul-yum_repository\/\">Das Modul yum_repository<\/a>] [5. <a href=\"https:\/\/www.my-it-brain.de\/wordpress\/ansible-die-module-copy-und-cron\/\">Die Module copy und cron<\/a>]<\/p>\n<p>Mit den Anregungen meines Arbeitskollegen habe ich dazu das folgende Playbook erstellt, welches die Rolle <em>rhel-patchmanagement<\/em> auf allen Hosts mit einem Red Hat Betriebssystem ausf\u00fchrt:<\/p>\n<pre>---\n- hosts: all\n\n  tasks:\n    - name: Group by OS\n      group_by: key=os_{{ ansible_distribution }}\n      changed_when: False\n\n- hosts: os_RedHat\n  roles:\n    - rhel-patchmanagement\n<\/pre>\n<p>Die Rolle&nbsp;<em>rhel-patchmanagement<\/em> besteht aus den beiden folgenden Dateien:<\/p>\n<ul>\n<li><em>roles\/patch_rhel\/tasks\/main.yml<\/em><\/li>\n<li><em>roles\/patch_rhel\/vars\/main.yml<\/em><\/li>\n<\/ul>\n<p><em>roles\/patch_rhel\/vars\/main.yml<\/em>:<\/p>\n<pre>---\nrhsa_to_install: RHSA-2016:1626,RHSA-2016:1628,RHSA-2016:1633\n<\/pre>\n<p>Obiges Listing gibt ein kurzes Beispiel, wie die Red Hat Security Advisory (RHSA) Nummern einer Variablen zugewiesen werden k\u00f6nnen. Die Variable <em>rhsa_to_install<\/em> wird dann in der Task-Datei verwendet.<\/p>\n<p><em>roles\/patch_rhel\/tasks\/main.yml<\/em>:<\/p>\n<pre>---\n  - name: Install Red Hat Security Advisory (RHSA)\n    command: yum -y update-minimal --advisory {{ rhsa_to_install }}\n    register: yum_output\n  - debug: var=yum_output\n\n  - name: Reboot Host if packages were updated\n    shell: sleep 2 &amp;&amp; shutdown -r now \"Ansible updates triggered\"\n    async: 1\n    poll: 0\n    ignore_errors: true\n    when: ('\"Complete!\" in \"{{ yum_output.stdout_lines[-1] }}\"') or\n          ('\"Komplett!\" in \"{{ yum_output.stdout_lines[-1] }}\"')\n\n  - name: waiting for access server\n    local_action: wait_for\n      host={{ inventory_hostname }}\n      state=started\n      port=22\n      delay=30\n      timeout=300\n      connect_timeout=15\n<\/pre>\n<p>Zuerst wird das Kommando zur Aktualisierung der zu den angegebenen RHSA geh\u00f6renden Pakete auf den Hosts ausgef\u00fchrt. Dabei wird die Ausgabe des Kommandos <code>yum<\/code> auf den Hosts der Variable <em>yum_output<\/em> zugewiesen.[6. <a href=\"https:\/\/docs.ansible.com\/ansible\/2.9\/user_guide\/playbooks_variables.html#registered-variables\" target=\"_blank\" rel=\"noopener noreferrer\">Registered Variables<\/a>] Diese Variable wird im n\u00e4chsten Schritt ausgewertet, um zu ermitteln, ob Pakete aktualisiert wurden. Ist dies der Fall, wird der Host neugestartet.<\/p>\n<p><em>Erkl\u00e4rung<\/em>: Wurden Pakete aktualisiert, steht in der letzten Zeile der YUM-Ausgabe der Ausdruck &#8222;Complete!&#8220;. <code>\"{{ yum_output.stdout_lines[-1] }}\"<\/code> dereferenziert die Variable und liefert die Ausgabe des YUM-Kommandos als Liste zur\u00fcck. Dabei wird in diesem Fall auf das letzte Element der Liste zugegriffen. Enth\u00e4lt diese Zeile den genannten Ausdruck, wird der Host neugestartet. <em>Hinweis:<\/em> Die zweite Zeile der when-Bedingung aus dem oberen Listing dient der Behandlung einer deutschsprachigen Ausgabe. In diesem Fall wird das Schl\u00fcsselwort &#8222;Komplett!&#8220; ausgegeben und in der Variable gespeichert.<\/p>\n<p>Der letzte Task wartet 30 Sekunden ab, um dem Host Zeit f\u00fcr den Neustart zu geben und pr\u00fcft, ob eine Verbindung hergestellt werden kann. Damit soll sichergestellt werden, dass der Host nach dem Neustart wieder korrekt hochf\u00e4hrt.<\/p>\n<p>Damit sind die Anforderungen aus Punkt 2 und 3 erf\u00fcllt. Um auch noch die Anforderung aus Punkt 1 zu erf\u00fcllen, setze ich folgendes Wrapper-Skript ein, welches das Playbook zu den definierten Stichtagen ausf\u00fchren soll:<\/p>\n<pre>#!\/bin\/sh\n\nDOM=`date +%d`\nDOW=`date +%w`\nLOG=\"\/var\/log\/ansible\/patch_run_`date +%Y-%m-%d`.log\"\nSETUP_LOG=\"\/var\/log\/ansible\/setup_patch_run_`date +%Y-%m-%d`.log\"\nSSH_KEY=\"\/pfad\/zum\/ssh-key\"\nPLAYBOOK=\"\/data\/ansible\/patch_rhel.yml\"\nCREATEVARS=\"\/pfad\/zu\/roles\/rhel-patchmanagement\/create_vars.sh\"\n\n# Run Patch-Management ad-hoc in the specified phase.\n# Example: '.\/run_rhel_patch_mgmt.sh NOW rhel-patch-phase1'\nif [ \"${1}\" = \"NOW\" ] &amp&amp [ -n \"${2}\" ]\nthen\n  ansible-playbook $PLAYBOOK --private-key=$SSH_KEY --limit=\"${2}\" &gt&gt$LOG 2&gt&amp1\n  exit\nfi\n\nif [ \"${1}\" = \"NOW\" ] &amp&amp [ -z \"${2}\" ]\nthen\n  echo \"ERROR: Second argument is missing.\"\n  echo \"Example: '.\/run_rhel_patch_mgmt.sh NOW rhel-patch-phase1'\"\n  exit\nfi\n\n# Setup the next patchcycle\nif [ \"$DOW\" = \"2\" ] &amp&amp [ \"$DOM\" -gt 0 ] &amp&amp [ \"$DOM\" -lt 8 ]\nthen\n    $CREATEVARS &gt $SETUP_LOG 2&gt&amp1\nfi\n\n# Patchcycle of the rhel-patch-phase1 on the second Tuesday of a month\nif [ \"$DOW\" = \"2\" ] &amp&amp [ \"$DOM\" -gt 7 ] &amp&amp [ \"$DOM\" -lt 15 ]\nthen\n    ansible-playbook $PLAYBOOK --private-key=$SSH_KEY --limit=rhel-patch-phase1 &gt $LOG 2&gt&amp1\nfi\n\n# Patchcycle of the rhel-patch-phase2 on the third Tuesday of a month\nif [ \"$DOW\" = \"2\" ] &amp&amp [ \"$DOM\" -gt 14 ] &amp&amp [ \"$DOM\" -lt 22 ]\nthen\n    ansible-playbook $PLAYBOOK --private-key=$SSH_KEY --limit=rhel-patch-phase2 &gt $LOG 2&gt&amp1\nfi\n\n# Patchcycle of the rhel-patch-phase3 on the fourth Tuesday of a month\nif [ \"$DOW\" = \"2\" ] &amp&amp [ \"$DOM\" -gt 21 ] &amp&amp [ \"$DOM\" -lt 29 ]\nthen\n    ansible-playbook $PLAYBOOK --private-key=$SSH_KEY --limit=rhel-patch-phase3 &gt $LOG 2&gt&amp1\nfi\n\n# Patchcycle of the rhel-patch-phase4 on the fourth Wednesday of a month\nif [ \"$DOW\" = \"3\" ] &amp&amp [ \"$DOM\" -gt 21 ] &amp&amp [ \"$DOM\" -lt 30 ]\nthen\n    ansible-playbook $PLAYBOOK --private-key=$SSH_KEY --limit=rhel-patch-phase4 &gt $LOG 2&gt&amp1\nfi<\/pre>\n<p>Mit diesem Wrapper-Skript m\u00f6chte ich daf\u00fcr sorgen, dass an jedem 2. Dienstag im Monat die RSHA-Aktualisierungen auf den Hosts in der rhel-patch-phase1, jeden 3. Dienstag in der rhel-patch-phase2, jeden 4. Dienstag in der rhel-patch-phase3 und jeden 4. Mittwoch in rhel-patch-phase4 installiert werden.<\/p>\n<p>So kann sichergestellt werden, dass die Informationen aus den RHSA alle Hosts erreichen. Gleichzeitig wird den Betreibern der Hosts die Gelegegnheit gegeben, die Aktualisierungen bis zu den genannten Stichtagen selbst einzuspielen. Damit sollte ich auch an Punkt 1 einen Haken dran machen k\u00f6nnen.<\/p>\n\n<p>Die Ansible-Rolle und dazugeh\u00f6rende Skripte und Beispiel-Dateien findet ihr auf:\n<ul>\n\t<li>Ansible Galaxy: <a href=\"https:\/\/galaxy.ansible.com\/tronde\/rhel-patchmanagement\" title=\"Role on Ansible Galaxy\">https:\/\/galaxy.ansible.com\/tronde\/rhel-patchmanagement<\/a><\/li>\n\t<li>GitHub: <a href=\"https:\/\/github.com\/Tronde\/ansible-role-rhel-patchmanagement\">https:\/\/github.com\/Tronde\/ansible-role-rhel-patchmanagement<\/a><\/li>\n<\/ul><\/p>\n<p>\n\tFragen zur Anwendung, Konfiguration und Nutzung des RHEL-Patchmanagements k\u00f6nnt ihr gerne auf GitHub oder hier in den Kommentaren stellen.\n<\/p>\n<p>\n\t<em>Aktualisiert am: 07.09.2018<\/em>\n<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Als Linux-Distribution f\u00fcr den Betrieb im Rechenzentrum fiel unsere Wahl vor einiger Zeit auf Red Hat Enterprise Linux. Zu meinen Aufgaben geh\u00f6rt es, ein Patch-Management f\u00fcr diese Systeme zu entwickeln, welches die folgenden Anforderungen erf\u00fcllt: Die zu aktualisierenden Hosts werden in Gruppen im Ansible Inventory verwaltet. Eine Gruppe entspricht dabei einer Stage\/Phase f\u00fcr das Patch-Management.<span class=\"continue-reading\"> <a href=\"https:\/\/www.my-it-brain.de\/wordpress\/ansible-patch-management-fuer-red-hat-systeme\/\">[Weiterlesen&#8230;]<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_metis_text_type":"","_metis_text_length":0,"_post_count":0,"footnotes":""},"categories":[532,51],"tags":[410,428,305,419],"class_list":["post-1563","post","type-post","status-publish","format-standard","hentry","category-ansible","category-linux","tag-ansible","tag-patch-management","tag-planet","tag-red-hat"],"_links":{"self":[{"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/posts\/1563","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/comments?post=1563"}],"version-history":[{"count":13,"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/posts\/1563\/revisions"}],"predecessor-version":[{"id":2743,"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/posts\/1563\/revisions\/2743"}],"wp:attachment":[{"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/media?parent=1563"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/categories?post=1563"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/tags?post=1563"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}