{"id":1686,"date":"2018-03-30T17:00:23","date_gmt":"2018-03-30T16:00:23","guid":{"rendered":"https:\/\/www.my-it-brain.de\/wordpress\/?p=1686"},"modified":"2020-06-21T13:27:13","modified_gmt":"2020-06-21T11:27:13","slug":"konzept-zum-deployment-meines-blogs-mit-ansible","status":"publish","type":"post","link":"https:\/\/www.my-it-brain.de\/wordpress\/konzept-zum-deployment-meines-blogs-mit-ansible\/","title":{"rendered":"Konzept zum Deployment meines Blogs mit Ansible"},"content":{"rendered":"<p>An dieser Stelle m\u00f6chte ich ein Konzept erarbeiten, um meinen Blog mit Hilfe von Ansible[1. <a href=\"https:\/\/www.my-it-brain.de\/wordpress\/ansible-it-automation-fuer-jedermann\/\">Ansible &#8211; IT-Automation f\u00fcr Jedermann &#8211; My-IT-Brain<\/a>] [2. <a href=\"https:\/\/de.wikipedia.org\/wiki\/Ansible\">Ansible &#8211; Wikipedia<\/a>] auf einem Ubuntu-Server ausbringen zu k\u00f6nnen.<\/p>\n<p>Dabei hoffe ich auch ein wenig auf eure Unterst\u00fctzung. Habt ihr Anregungen, konkrete Verbesserungsvorschl\u00e4ge oder auch Fragen, freue ich mich \u00fcber eure Kommentare. Denn ich selbst bin kein Ansible-Experte und f\u00fchre dieses Projekt zum Selbststudium und zu \u00dcbungszwecken durch.<\/p>\n<h2 id=\"Testumgebung\">Die Testumgebung<\/h2>\n<p>Die Testumgebung besteht aus der <em>Ansible Control Machine<\/em>, basierend auf RHEL 7[3. <a href=\"https:\/\/de.wikipedia.org\/wiki\/Red_Hat_Enterprise_Linux\">Red Hat Enterprise Linux &#8211; Wikipedia<\/a>] und dem Zielsystem, basierend auf Ubuntu Bionic Beaver[4. <a href=\"https:\/\/wiki.ubuntuusers.de\/Bionic_Beaver\/\">Bionic Beaver &#8211; wiki.ubuntuusers.de<\/a>]. Zum Zeitpunkt der Erstellung dieses Artikels nutze ich Ansible in Version 2.4.2.<\/p>\n<p>Zwar wurde bereits die Ansible-Version 2.5 ver\u00f6ffentlicht, in den RHEL-7-Paketquellen ist jedoch noch die Version 2.4.2 enthalten. Ich verwende diese Version auch auf der Arbeit und erhoffe mir so, Erkenntnisse aus diesem Projekt in meine dienstliche T\u00e4tigkeit einflie\u00dfen lassen zu k\u00f6nnen.<\/p>\n<p>Auf dem Zielsystem existiert ein Benutzer, welcher \u00fcber volle <code>sudo<\/code>-Berechtigung verf\u00fcgt. Dieser Benutzer muss sich mit seinem Passwort authentisieren, wenn er <code>sudo<\/code> verwendet.<\/p>\n<p>Auf der <em>Ansible Control Machine<\/em> wird ein SSH-Schl\u00fcsselpaar[5. <a href=\"https:\/\/wiki.ubuntuusers.de\/SSH\/#Authentifizierung-ueber-Public-Keys\">Authentifizierung \u00fcber Public-Keys &#8211; wiki.ubuntuusers.de<\/a>] generiert, dessen privater Schl\u00fcssel nicht mit einer Passphrase gesch\u00fctzt ist. Der \u00f6ffentliche Schl\u00fcssel wird auf dem Zielsystem abgelegt. Damit wird sichergestellt, dass die <em>Ansible Control Machine<\/em> SSH-Zugriff auf das Zielsystem hat.<\/p>\n<p>Die Konfiguration von Ansible (\/etc\/ansible\/ansible.cfg) wird so angepasst, dass standardm\u00e4\u00dfig das oben erzeugte SSH-Private-Key-File beim Verbindungsaufbau genutzt wird.<\/p>\n<p>Die Installation der ben\u00f6tigten Betriebssysteme und Ansible sind nicht Gegenstand dieses Artikels.<\/p>\n<h2 id=\"Vorgehensweise\">Geplante Vorgehensweise<\/h2>\n<p>Um eine Vorgehensweise zu erarbeiten, orientiere ich mich an dem Artikel <a href=\"https:\/\/www.my-it-brain.de\/wordpress\/testinstanz-fuer-einen-wordpress-blog-erstellen\/\">Testinstanz f\u00fcr einen WordPress-Blog erstellen<\/a>. In diesem habe ich bereits beschrieben, wie ein Blog auf einem weiteren System als Testsystem aufgesetzt werden kann. Die Vorgehensweise ist \u00e4hnlich, mit dem Unterschied, dass s\u00e4mtliche Schritte nun durch Ansible orchestriert werden sollen.<\/p>\n<p>Danach ergibt sich folgende (vorl\u00e4ufige) Reihenfolge:<\/p>\n<ol>\n<li>Vom Produktivsystem ben\u00f6tigte Dateien holen<\/li>\n<li>Sicherstellen, das alle ben\u00f6tigten Pakete auf dem Zielsystem installiert sind<\/li>\n<li>VirtualHost erstellen<\/li>\n<li>DocumentRoot aus Backup-Datei erstellen<\/li>\n<li>Datei-Attribute und Zugriffsrechte korrekt setzen<\/li>\n<li>Eine <code>.httpasswd<\/code>-Datei erzeugen\/ausbringen<\/li>\n<li>Datenbank aus Backup wiederherstellen<\/li>\n<li>Datenbankbenutzer erstellen<\/li>\n<li>Troubleshooting<\/li>\n<\/ol>\n<p>Mit hoher Wahrscheinlichkeit ist die obige Liste noch nicht vollst\u00e4ndig. Daher werde ich diese im Laufe des Projekts anpassen, sobald weitere Erkenntnisse vorliegen.<\/p>\n<p>Als Quelldaten f\u00fcr den Blog liegen das DocumentRoot meines Blogs als Tarball[6. <a href=\"https:\/\/de.wikipedia.org\/wiki\/Tar\">tar &#8211; Wikipedia<\/a>] vor. Von der Datenbank wurde ein logisches Backup[7. <a href=\"https:\/\/wiki.ubuntuusers.de\/MySQL\/Backup\/#Logisches-Backup\">Logisches Backup &#8211; wiki.ubuntuusers.de<\/a>] erstellt. Auf diese Datensicherung wird zur\u00fcckgegriffen, um den Blog auf einem neuen Ubuntu-Server auszubringen bzw. wiederherzustellen.<\/p>\n<h2 id=\"der-erste-versuch\">Der erste Versuch<\/h2>\n<p>Im ersten Anlauf habe ich eine Ansible-Rolle[8. <a href=\"http:\/\/docs.ansible.com\/ansible\/latest\/user_guide\/playbooks_best_practices.html#directory-layout\">Directory Layout &#8212; Ansible Best Practices<\/a>] mit folgendem Aufbau erstellt:<\/p>\n<pre>\/etc\/ansible\/roles\/\n\u2514\u2500\u2500 deploy-my-blog\n    \u251c\u2500\u2500 files\n    \u2502\u00a0\u00a0 \u251c\u2500\u2500 backup-documentroot.tar.bz2\n    \u2502\u00a0\u00a0 \u251c\u2500\u2500 dh_params.pem\n    \u2502\u00a0\u00a0 \u251c\u2500\u2500 db_dump.sql.bz2\n    \u2502\u00a0\u00a0 \u251c\u2500\u2500 my-it-brain.vhost\n    \u2502\u00a0\u00a0 \u2514\u2500\u2500 php-fpm-pool.conf\n    \u251c\u2500\u2500 handlers\n    \u2502\u00a0\u00a0 \u2514\u2500\u2500 main.yml\n    \u251c\u2500\u2500 tasks\n    \u2502\u00a0\u00a0 \u2514\u2500\u2500 main.yml\n    \u2514\u2500\u2500 vars\n        \u2514\u2500\u2500 main.yml\n\n5 directories, 8 files\n<\/pre>\n<p>Unterhalb von <em>files<\/em> wurden Dateien abgelegt, welche vom aktuellen Produktivsystem stammen und f\u00fcr das Deployment auf einem neuen Server ben\u00f6tigt werden.<\/p>\n<p>Im folgenden werde ich zuerst auf die eingesetzten Module eingehen und anschlie\u00dfend das Playbook zum Deployment des Blogs vorstellen.<\/p>\n<h3 id=\"verwendete-module\">Verwendete Module<\/h3>\n\n<table id=\"tablepress-9\" class=\"tablepress tablepress-id-9\">\n<thead>\n<tr class=\"row-1\">\n\t<th class=\"column-1\">Modul<\/th><th class=\"column-2\">Status<\/th><th class=\"column-3\">Verwendung<\/th>\n<\/tr>\n<\/thead>\n<tbody class=\"row-striping row-hover\">\n<tr class=\"row-2\">\n\t<td class=\"column-1\"><a href=\"https:\/\/docs.ansible.com\/ansible\/2.4\/apt_module.html\" rel=\"noopener noreferrer\" target=\"_blank\">apt<\/a><\/td><td class=\"column-2\">stableinterface<\/td><td class=\"column-3\">Verwaltet APT-Pakete<\/td>\n<\/tr>\n<tr class=\"row-3\">\n\t<td class=\"column-1\"><a href=\"https:\/\/docs.ansible.com\/ansible\/2.4\/unarchive_module.html\" rel=\"noopener noreferrer\" target=\"_blank\">unarchive<\/a><\/td><td class=\"column-2\">preview<\/td><td class=\"column-3\">Entpackt Archiv-Dateien und kopiert sie ggf. vorher auf das Zielsystem<\/td>\n<\/tr>\n<tr class=\"row-4\">\n\t<td class=\"column-1\"><a href=\"https:\/\/docs.ansible.com\/ansible\/2.4\/copy_module.html\" rel=\"noopener noreferrer\" target=\"_blank\">copy<\/a><\/td><td class=\"column-2\">stableinterface<\/td><td class=\"column-3\">Kopiert Dateien auf entfernte Rechner<\/td>\n<\/tr>\n<tr class=\"row-5\">\n\t<td class=\"column-1\"><a href=\"https:\/\/docs.ansible.com\/ansible\/2.4\/file_module.html\" rel=\"noopener noreferrer\" target=\"_blank\">file<\/a><\/td><td class=\"column-2\">stableinterface<\/td><td class=\"column-3\">Erstellt Dateien, Verzeichnisse, symbolische Links und setzt deren Attribute<\/td>\n<\/tr>\n<tr class=\"row-6\">\n\t<td class=\"column-1\"><a href=\"https:\/\/docs.ansible.com\/ansible\/2.4\/mysql_db_module.html\" rel=\"noopener noreferrer\" target=\"_blank\">mysql_db<\/a><\/td><td class=\"column-2\">preview<\/td><td class=\"column-3\">Hinzuf\u00fcgen von MySQL-Datenbanken (aus Backup)<\/td>\n<\/tr>\n<tr class=\"row-7\">\n\t<td class=\"column-1\"><a href=\"https:\/\/docs.ansible.com\/ansible\/2.4\/mysql_user_module.html\" rel=\"noopener noreferrer\" target=\"_blank\">mysql_user<\/a><\/td><td class=\"column-2\">preview<\/td><td class=\"column-3\">Hinzuf\u00fcgen (und Entfernen) von Benutzern in MySQL-Datenbanken<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<!-- #tablepress-9 from cache -->\n<p>Die in der Spalte Status angegebenen Werte <strong>stableinterface<\/strong> und <strong>preview<\/strong> lassen R\u00fcckschl\u00fcsse auf die Stabilit\u00e4t der Schnittstellen eines Moduls zu.<\/p>\n<p>So garantieren die Entwickler bei einem <strong>stableinterface<\/strong>, dass es in Zukunft keine \u00c4nderungen geben wird, die nicht abw\u00e4rtskompatibel sind. Auch wenn sich keine explizite Angabe findet, wie lange diese Garantie gilt, kann man davon ausgehen, dass man seine Playbooks bei Verwendung dieser Module nicht so schnell aufgrund von Updates anpassen muss. F\u00fcr Module mit dem Status <strong>preview<\/strong> wird genau dies hingegen nicht garantiert. Hier kann es von Version zu Version \u00c4nderungen geben, welche Anpassungen an Playbooks erforderlich machen, welche diese Module verwenden. Dadurch entsteht ggf. ein erh\u00f6hter Testaufwand, bevor man seine Ansible-Installation aktualisieren kann.<\/p>\n<h3 id=\"deploy-blog-playbook\">Das Playbook<\/h3>\n<p>Den Inhalt der Datei <em>\/etc\/ansible\/roles\/deploy-my-blog\/tasks\/main.yml<\/em> habe ich unter dem Namen <em>deploy-blog-playbook.yml<\/em> als <a href=\"https:\/\/gist.github.com\/Tronde\/db576c10b6889470de80eaa659d7980a\">Gist<\/a> ver\u00f6ffentlicht. Um es in diesem Artikel anzeigen zu k\u00f6nnen, m\u00fcsst ihr JavaScript in eurem Webbrowser aktiveren.<\/p>\n<p><script src=\"https:\/\/gist.github.com\/Tronde\/db576c10b6889470de80eaa659d7980a.js\"><\/script><\/p>\n<p>Die Zeilen 2-11 sorgen daf\u00fcr, dass die ben\u00f6tigten Pakete auf dem Zielsystem installiert werden. Da es sich dabei um einen Ubuntu-Server handelt, verwende ich das Modul <a href=\"http:\/\/docs.ansible.com\/ansible\/2.4\/apt_module.html\">apt<\/a>.<\/p>\n<p>Die Zeilen 13-16 stellen das DocumentRoot und die SSL-Zertifikate aus dem Dateibackup auf dem Zielsystem wieder her.<\/p>\n<p>In meiner aktuellen Konfiguration verwende ich PHP-FPM mit einem eigenen Pool, welcher in meinem VirtualHost referenziert wird. Um diese Konstellation auch auf dem neuen System nutzen zu k\u00f6nnen, stelle ich entsprechende Konfiguration mit den Zeilen 18-47 her. Vermutlich k\u00f6nnen die Zeilen 39-47 entfallen, da PHP-FPM das Logfile automatisch erstellt. Weitere Tests m\u00fcssen dies noch zeigen. Ich habe diese Zeilen w\u00e4hrend des Troubleshootings eingef\u00fcgt. Ursache f\u00fcr den Fehler wird vermutlich das fehlende Log-Verzeichnis gewesen sein, welches ich in den Zeilen 29-37 erzeuge.<\/p>\n<p>Der NGINX auf meinem Produktivsystem verwendet die Datei <em>dh_params.pem<\/em>, welche ich in den Zeilen 49-57 auch auf den neuen Host kopiere. Anschlie\u00dfend wird in den Zeilen 59-66 die vHost-Datei auf das Zielsystem kopiert und durch die Zeilen 68-77 verlinkt und damit aktiviert.<\/p>\n<p>Die letzten Zeilen k\u00fcmmern sich um die Einrichtung der Datenbank. Zuerst wird die Dump-Datei auf das Zielsystem kopiert und dort anschlie\u00dfend in die neue Datenbank <em>db_my_it_brain<\/em> eingespielt. Zum Schluss wird noch der ben\u00f6tigte Datenbank-Benutzer erstellt.<\/p>\n<p>In Zeile 94 und 95 habe ich Variablen eingesetzt, welche in <em>vars\/main.yml<\/em> definiert wurden. Dort habe ich auch eine Variable f\u00fcr den Namen der Datenbank definiert, welche ich gern in Zeile 96 genutzt h\u00e4tte. Leider ist es mir nicht gelungen, da sowohl <code>priv: '\"{{ DBNAME }}\".*:ALL'<\/code> als auch <code>priv: \"{{ DBNAME }}\".*:ALL<\/code> zu Fehlern f\u00fchrten. Falls hier jemand eine Idee hat, freue ich mich, wenn ihr mir die korrekte Syntax mitteilt.<\/p>\n<h2>Erstes Fazit<\/h2>\n<p>Das ging leichter als gedacht. Die ben\u00f6tigten Module waren schnell gefunden und ihre Anwendung aufgrund der hinreichend guten Dokumentation nicht schwierig.<\/p>\n<p>Da die aktuell genutzten Variablen sensible Informationen beinhalten, m\u00f6chte ich diese zuk\u00fcnftig mit <a href=\"http:\/\/docs.ansible.com\/ansible\/2.4\/vault.html\">Ansible Vault<\/a> sch\u00fctzen.<\/p>\n<p>Stand heute bin ich jedoch erstmal in der Lage meinen Blog aus der Datensicherung heraus erneut deployen zu k\u00f6nnen.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>An dieser Stelle m\u00f6chte ich ein Konzept erarbeiten, um meinen Blog mit Hilfe von Ansible[1. Ansible &#8211; IT-Automation f\u00fcr Jedermann &#8211; My-IT-Brain] [2. Ansible &#8211; Wikipedia] auf einem Ubuntu-Server ausbringen zu k\u00f6nnen. Dabei hoffe ich auch ein wenig auf eure Unterst\u00fctzung. Habt ihr Anregungen, konkrete Verbesserungsvorschl\u00e4ge oder auch Fragen, freue ich mich \u00fcber eure Kommentare.<span class=\"continue-reading\"> <a href=\"https:\/\/www.my-it-brain.de\/wordpress\/konzept-zum-deployment-meines-blogs-mit-ansible\/\">[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,57],"tags":[410,430,305,338],"class_list":["post-1686","post","type-post","status-publish","format-standard","hentry","category-ansible","category-wochenend-projekte","tag-ansible","tag-osbn","tag-planet","tag-wordpress"],"_links":{"self":[{"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/posts\/1686","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=1686"}],"version-history":[{"count":19,"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/posts\/1686\/revisions"}],"predecessor-version":[{"id":2541,"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/posts\/1686\/revisions\/2541"}],"wp:attachment":[{"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/media?parent=1686"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/categories?post=1686"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/tags?post=1686"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}