{"id":1701,"date":"2016-12-17T12:50:31","date_gmt":"2016-12-17T11:50:31","guid":{"rendered":"https:\/\/www.my-it-brain.de\/wordpress\/?p=1701"},"modified":"2021-01-25T13:01:34","modified_gmt":"2021-01-25T12:01:34","slug":"ansible-was-ich-am-ad-hoc-modus-schaetze","status":"publish","type":"post","link":"https:\/\/www.my-it-brain.de\/wordpress\/ansible-was-ich-am-ad-hoc-modus-schaetze\/","title":{"rendered":"Ansible &#8211; Was ich am Ad-hoc-Modus sch\u00e4tze"},"content":{"rendered":"<p>Schon seit einiger Zeit hilft mir Ansible[1. <a href=\"https:\/\/www.my-it-brain.de\/wordpress\/ansible-it-automation-fuer-jedermann\/\">Ansible &#8211; IT-Automation f\u00fcr Jedermann<\/a>] fast t\u00e4glich dabei, meine Arbeit leichter zu gestalten. Heute m\u00f6chte ich euch ganz kurz erz\u00e4hlen, was ich am Ad-hoc-Modus sch\u00e4tze.<\/p>\n<p>Der Ad-hoc-Modus bietet die M\u00f6glichkeit, einfache Kommandos parallel auf einer Gruppe von Nodes ausf\u00fchren zu lassen, ohne zuvor ein Playbook erstellen zu m\u00fcssen. Ein Ad-hoc-Befehl besitzt z.B. den folgenden Aufbau:<br \/>\n<code><br \/>\nansible [-m module_name] [-a args] [options]<br \/>\n<\/code><\/p>\n<p>Ein einfaches Beispiel aus der Ansible-Dokumentation[2. <a href=\"http:\/\/docs.ansible.com\/ansible\/2.9\/user_guide\/intro_adhoc.html\" target=\"_blank\" rel=\"noopener noreferrer\">Introduction To Ad-Hoc Commands<\/a> {en}] soll die Anwendung verdeutlichen:<br \/>\n<code><br \/>\n# ansible all -m ping -i staging --limit=e-stage<br \/>\nhost01.example.com | SUCCESS =&gt; {<br \/>\n\"changed\": false,<br \/>\n\"ping\": \"pong\"<br \/>\n}<br \/>\nhost02.example.com | SUCCESS =&gt; {<br \/>\n\"changed\": false,<br \/>\n\"ping\": \"pong\"<br \/>\n}<br \/>\nhost03.example.com | SUCCESS =&gt; {<br \/>\n\"changed\": false,<br \/>\n\"ping\": \"pong\"<br \/>\n}<br \/>\n<\/code><\/p>\n<p>Das Schl\u00fcsselwort <code>all<\/code> gibt an, dass das Kommando auf allen Nodes ausgef\u00fchrt werden soll, welche in der Inventar-Datei enthalten sind. Mit <code>-m ping<\/code> wird das zu verwendende Ansible-Modul spezifiziert. Da das verwendete Modul keine weiteren Argumente besitzt, findet <code>-a<\/code> in diesem Beispiel keine Anwendung. Mit der Option <code>-i<\/code> kann die zu verwendende Inventar-Datei angegeben werden. L\u00e4sst man diese Option weg, wird die Standard-Inventar-Datei <code>\/etc\/ansible\/hosts<\/code> verwendet. Mit der Option <code>--limit=e-stage<\/code> wird die Ausf\u00fchrung noch weiter eingeschr\u00e4nkt. So wird in diesem Fall das Modul <code>ping<\/code> nur auf den Nodes der Gruppe <code>e-stage<\/code> ausgef\u00fchrt. Das in diesem Beispiel verwendete Inventar besitzt den folgenden Aufbau:<\/p>\n<pre>[e-stage]\r\nhost01.example.com\r\nhost02.example.com\r\nhost03.example.com\r\nhost06.example.com\r\nhost07.example.com\r\n\r\n[i-stage]\r\nhost04.example.com\r\n\r\n[p-stage]\r\nhost05.example.com\r\n<\/pre>\n<h2>Verkn\u00fcpfung mit weiteren Kommandos<\/h2>\n<p>Selbstverst\u00e4ndlich lassen sich Ansible-Ad-hoc-Kommandos auf der Kommandozeile auch weiter verkn\u00fcpfen. Dies soll an zwei kleinen Beispielen verdeutlicht werden.<\/p>\n<h3>Status eines Dienstes pr\u00fcfen<\/h3>\n<p>In diesem ersten Beispiel soll der Status des Dienstes <code>chronyd<\/code> \u00fcberpr\u00fcft werden, ohne den aktuellen Status zu \u00e4ndern. Dabei soll das Kommando <code>systemctl status chronyd.service<\/code> via Ansible parallel auf den Nodes ausgef\u00fchrt werden.<\/p>\n<p>Zuvor habe ich mir auf einem Node angesehen, wie die Ansible-Ausgabe in Abh\u00e4ngigkeit vom Dienststatus aussieht (Ausgabe gek\u00fcrzt):<br \/>\n<code><br \/>\n# Der Dienst auf dem Node ist gestartet<br \/>\nroot@ansible-control-machine&gt;ansible all -m command -a'\/usr\/bin\/systemctl status chronyd.service' -i staging -l host01.example.com<br \/>\nhost01.example.com | SUCCESS | rc=0 &gt;&gt;<br \/>\n* chronyd.service - NTP client\/server<br \/>\nLoaded: loaded (\/usr\/lib\/systemd\/system\/chronyd.service; enabled; vendor preset: enabled)<br \/>\nActive: active (running) since Thu 2016-12-15 14:52:02 CET; 19h ago<\/code><\/p>\n<p># Der Dienst auf dem Node ist gestoppt<br \/>\nroot@ansible-control-machine&gt;ansible all -m command -a&#8217;\/usr\/bin\/systemctl status chronyd.service&#8216; -i staging -l host01.example.com<br \/>\nhost01.example.com | FAILED | rc=3 &gt;&gt;<br \/>\n* chronyd.service &#8211; NTP client\/server<br \/>\nLoaded: loaded (\/usr\/lib\/systemd\/system\/chronyd.service; enabled; vendor preset: enabled)<br \/>\nActive: inactive (dead) since Fri 2016-12-16 10:04:34 CET; 4s ago<\/p>\n<p># Das Paket, welches den Dienst enthaelt ist nicht installiert<br \/>\nroot@ansible-control-machine&gt;ansible all -m command -a&#8217;\/usr\/bin\/systemctl status chronyd.service&#8216; -i staging -l host01.example.com<br \/>\nhost01.example.com | FAILED | rc=4 &gt;&gt;<br \/>\nUnit chronyd.service could not be found.<\/p>\n<p>Anhand der Ausgaben ist zu erkennen, dass Ansible den Task als &#8222;| SUCCESS |&#8220; markiert, wenn der Dienst l\u00e4uft und als &#8222;| FAILED |&#8220;, wenn der Dienst gestoppt bzw. gar nicht installiert ist. Durch Verkn\u00fcpfung des Kommandos mit <code>grep<\/code> kann man sich nun schnell einen \u00dcberblick \u00fcber den Dienststatus auf seinen Rechnern verschaffen:<br \/>\n<code><br \/>\nroot@ansible-control-machine&gt; ansible all -m command -a'\/usr\/bin\/systemctl status chronyd.service' -i staging --limit=e-stage | grep '| SUCCESS |\\|| FAILED |'<br \/>\nhost01.example.com | SUCCESS | rc=0 &gt;&gt;<br \/>\nhost02.example.com | SUCCESS | rc=0 &gt;&gt;<br \/>\nhost03.example.com | FAILED | rc=3 &gt;&gt;<br \/>\nhost06.example.com | SUCCESS | rc=0 &gt;&gt;<br \/>\nhost07.example.com | SUCCESS | rc=0 &gt;&gt;<br \/>\n<\/code><\/p>\n<p>Anhand der Ausgabe ist leicht zu erkennen, dass der Dienst <code>chronyd<\/code> auf host03 nicht l\u00e4uft. Anhand des Return-Codes <code>rc=3<\/code> l\u00e4sst sich weiterhin erkennen, dass das notwendige Paket offensichtlich installiert ist, der Dienst jedoch nicht gestartet wurde. Dies kann nun jedoch schnell durch folgenden Befehl korrigiert werden (Ausgabe gek\u00fcrzt):<br \/>\n<code><br \/>\nroot@ansible-control-machine&gt;ansible host03.example.com -m systemd -a'name=chronyd state=started' -i staging<br \/>\nhost03.example.com | SUCCESS =&gt; {<br \/>\n\"changed\": true,<br \/>\n\"name\": \"chronyd\",<br \/>\n\"state\": \"started\",<br \/>\n\"status\": {...}<br \/>\n}<br \/>\n<\/code><\/p>\n<p>Eine erneute Ausf\u00fchrung des ersten Kommandos best\u00e4tigt, dass der Dienst nun auch auf dem Node host03 ausgef\u00fchrt wird.<br \/>\n<code><br \/>\nroot@ansible-control-machine&gt; ansible all -m command -a'\/usr\/bin\/systemctl status chronyd.service' -i staging --limit=e-stage | grep '| SUCCESS |\\|| FAILED |'<br \/>\nhost01.example.com | SUCCESS | rc=0 &gt;&gt;<br \/>\nhost02.example.com | SUCCESS | rc=0 &gt;&gt;<br \/>\nhost03.example.com | SUCCESS | rc=0 &gt;&gt;<br \/>\nhost06.example.com | SUCCESS | rc=0 &gt;&gt;<br \/>\nhost07.example.com | SUCCESS | rc=0 &gt;&gt;<br \/>\n<\/code><\/p>\n<h3>Paketversion \u00fcberpr\u00fcfen<\/h3>\n<p>In diesem Beispiel m\u00f6chte ich die installierte Version des Pakets <code>tzdata<\/code> abfragen. Dies geschieht auf einem einzelnen Host mit dem Kommando <code>rpm -qi <\/code>:<br \/>\n<code><br \/>\n# rpm -qi tzdata<br \/>\nName : tzdata<br \/>\nVersion : 2016i<br \/>\nRelease : 1.el7<br \/>\nArchitecture: noarch<br \/>\nInstall Date: Wed Nov 9 08:47:03 2016<br \/>\nGroup : System Environment\/Base<br \/>\nSize : 1783642<br \/>\nLicense : Public Domain<br \/>\nSignature : RSA\/SHA256, Fri Nov 4 17:21:59 2016, Key ID 199e2f91fd431d51<br \/>\nSource RPM : tzdata-2016i-1.el7.src.rpm<br \/>\nBuild Date : Thu Nov 3 12:46:39 2016<br \/>\nBuild Host : ppc-045.build.eng.bos.redhat.com<br \/>\nRelocations : (not relocatable)<br \/>\nPackager : Red Hat, Inc. &lt;http:\/\/bugzilla.redhat.com\/bugzilla&gt;<br \/>\nVendor : Red Hat, Inc.<br \/>\nURL : https:\/\/www.iana.org\/time-zones<br \/>\nSummary : Timezone data<br \/>\nDescription :<br \/>\nThis package contains data files with rules for various timezones around<br \/>\nthe world.<br \/>\n<\/code><\/p>\n<p>Mich interessiert lediglich die zweite Zeile, welche die Version des Pakets enth\u00e4lt. Die frage ich nun wie folgt ab:<br \/>\n<code><br \/>\nroot@ansible-control-machine&gt; ansible all -m command -a'\/usr\/bin\/rpm -qi tzdata' -i staging --limit=e-stage | grep 'SUCCESS\\|Version'<br \/>\nhost01.example.com | SUCCESS | rc=0 &gt;&gt;<br \/>\nVersion : 2016f<br \/>\nhost02.example.com | SUCCESS | rc=0 &gt;&gt;<br \/>\nVersion : 2016g<br \/>\nhost03.example.com | SUCCESS | rc=0 &gt;&gt;<br \/>\nVersion : 2016i<br \/>\nhost06.example.com | SUCCESS | rc=0 &gt;&gt;<br \/>\nVersion : 2016i<br \/>\nhost07.example.com | SUCCESS | rc=0 &gt;&gt;<br \/>\nVersion : 2016i<br \/>\n<\/code><\/p>\n<p>Ohne Ansible h\u00e4tte ich diese Aufgaben entweder mit Iteration in einem kurzen Shell-Skript l\u00f6sen m\u00fcssen, oder zuerst ein Kochbuch, Manifest, etc. schreiben, welches dann anschlie\u00dfend ausgef\u00fchrt werden kann. So wurde mir hingegen einiges an Zeit gespart, die ich f\u00fcr andere Dinge verwenden konnte.<\/p>\n<p><strong>Quellen und weiterf\u00fchrende Links<\/strong><\/p>\n<ul>\n<li><a href=\"https:\/\/www.my-it-brain.de\/wordpress\/ansible-patch-management-fuer-red-hat-systeme\/\">Ansible: Patch-Management f\u00fcr Red Hat Systeme<\/a><\/li>\n<li><a href=\"https:\/\/www.my-it-brain.de\/wordpress\/ansible-die-module-copy-und-cron\/\">Ansible &#8211; Die Module copy und cron<\/a><\/li>\n<li><a href=\"https:\/\/www.my-it-brain.de\/wordpress\/ansible-das-modul-yum_repository\/\">Ansible &#8211; Das Modul yum_repository<\/a><\/li>\n<li><a href=\"https:\/\/www.my-it-brain.de\/wordpress\/linux-benutzerkonten-mit-ansible-verwalten\/\">Linux-Benutzerkonten mit Ansible verwalten<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Schon seit einiger Zeit hilft mir Ansible[1. Ansible &#8211; IT-Automation f\u00fcr Jedermann] fast t\u00e4glich dabei, meine Arbeit leichter zu gestalten. Heute m\u00f6chte ich euch ganz kurz erz\u00e4hlen, was ich am Ad-hoc-Modus sch\u00e4tze. Der Ad-hoc-Modus bietet die M\u00f6glichkeit, einfache Kommandos parallel auf einer Gruppe von Nodes ausf\u00fchren zu lassen, ohne zuvor ein Playbook erstellen zu m\u00fcssen.<span class=\"continue-reading\"> <a href=\"https:\/\/www.my-it-brain.de\/wordpress\/ansible-was-ich-am-ad-hoc-modus-schaetze\/\">[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,430,305,45],"class_list":["post-1701","post","type-post","status-publish","format-standard","hentry","category-ansible","category-linux","tag-ansible","tag-osbn","tag-planet","tag-tipps"],"_links":{"self":[{"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/posts\/1701","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=1701"}],"version-history":[{"count":7,"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/posts\/1701\/revisions"}],"predecessor-version":[{"id":2740,"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/posts\/1701\/revisions\/2740"}],"wp:attachment":[{"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/media?parent=1701"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/categories?post=1701"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/tags?post=1701"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}