Ansible all the Things
This is a modal window.
The media could not be loaded, either because the server or network failed or because the format is not supported.
Formal Metadata
Title |
| |
Subtitle |
| |
Alternative Title |
| |
Title of Series | ||
Number of Parts | 49 | |
Author | ||
License | CC Attribution 4.0 International: You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor. | |
Identifiers | 10.5446/51746 (DOI) | |
Publisher | ||
Release Date | ||
Language |
Content Metadata
Subject Area | ||
Genre | ||
Abstract |
|
FrOSCon 2020 Cloud-Edition34 / 49
1
2
5
8
9
10
13
19
20
21
22
23
25
26
27
29
31
32
33
34
35
42
44
46
48
00:00
Point cloudOpen sourceOrder theoryControl flow graphMainframe computerInventor <Programm>RollbewegungServer (computing)VarianceInformationMainframe computerTemplate (C++)RollbewegungParallelverarbeitungTwitterIP addressDemosceneDefault (computer science)SNMPComputer fileVariable (mathematics)Configuration spaceOpen sourcePasswordFirewall (computing)Musical ensembleComputer animation
05:39
RollbewegungBackupmakeAgent <Informatik>Gastropod shellService (economics)Debian GNU/LINUXServer (computing)DemoscenePlug-in (computing)Variable (mathematics)Distribution (mathematics)Human resource management systemTask (computing)BackupPasswordMainframe computerGit <Software>Grand Unified TheoryDefault (computer science)NagiosBASICVarianceSoftwareClient (computing)Operating systemLoginWorkstation <Musikinstrument>ZeitsynchronisationDemosceneBlock (periodic table)AutomatonLAMP <Programmpaket>Beam (structure)Computer fileServer (computing)Debian GNU/LINUXDevice driverSynchronizationJSON
11:12
Mainframe computerSNMPTask (computing)SoftwareGRADELocal ringMobile appService (economics)Mainframe computerIP addressCache (computing)Source code
15:22
Task (computing)SoftwareLINUXTINA <Telekommunikation>Service (economics)Cache (computing)Task (computing)EthernetVarianceComputer hardwareDebian GNU/LINUXMainframe computerOperating systemConfiguration spaceString (computer science)IP addressDistribution (mathematics)Template (C++)Knowledge-based configurationHOLRivenService (economics)Data storage deviceService PackDevice driverComputer fileGastropod shellRollbewegungRepresentational state transferVariable (mathematics)CASHEHTTP cookieInternetGoogle BloggerProfessional network serviceData center
23:11
Task (computing)Service (economics)Flock (web browser)DownloadAPIConvex hullTask (computing)Computer fileRollbewegungMoment (mathematics)Computer data loggingQuery languageVariable (mathematics)Service (economics)Apple <Marke>Template (C++)VarianceScripting languageDefault (computer science)Mainframe computerSource codeComputer animation
31:01
Task (computing)Convex hullFlock (web browser)Configuration spaceUpdateDemosceneService (economics)Human resource management systemSource code
32:18
Task (computing)Configuration spaceUpdateFlock (web browser)Task (computing)PasswordHuman resource management systemService (economics)DemosceneMainframe computer
34:15
CodePasswordCodeSoftware repositoryWebsiteSlide ruleComputer animation
35:41
CodeSlide ruleSoftware repositoryComputer animation
36:28
CodeCodeSlide ruleRollbewegungComputer animation
36:58
Point cloudJSONXMLUML
Transcript: German(auto-generated)
00:07
So, herzlich willkommen in Hörsaal 1.2. Wir hören jetzt von Heiko Borcha's Ansible All the Things. Willkommen zu meinem Talk Ansible All the Things, was mir dabei geholfen hat, mit Ansible eigentlich alles zu automatisieren.
00:22
Erstmal kurz über mich. Ich arbeite jetzt seit zwei Jahren unter dem schönen neuen Buzzword DevOps Engineer bzw. DevOps Architect. Ich mache hauptsächlich Cloud Infrastructure und wenn es geht, automatisiere ich mir am liebsten alles weg.
00:41
Dafür nutze ich normalerweise Terraform und Ansible. Terraform wird jetzt aber weniger, weil Ansible tatsächlich immer mächtiger geworden ist und auch die Sachen machen kann, die Terraform machen kann. Dann meine Motivation. Ansible ist einfach das Tool der Wahl für mich. Auf Twitter habe ich viel gelesen in den letzten Jahren bzw.
01:02
hauptsächlich auch vor dem Congress. Das ja sieht cool aus. Wie kann ich das denn lernen? Wo steige ich ein? Und warum ich Ansible so toll finde? Es ist agentless. Es braucht keine zentrale Infrastruktur. Es ist relativ leicht zu lernen.
01:20
Es ist open source. Und es ist ja eigentlich idempotent. Wenn ich eine Ansible-Rolle fünfmal anwende, kommt immer das gleiche Ergebnis raus. Es verändert sich nach dem ersten Anwenden. Es sollte sich eigentlich nichts mehr verändern. Da komme ich aber gleich zu spätestens bei der Demo.
01:41
Man muss schon ein bisschen Arbeit reinstecken, damit wirklich auch das Ergebnis dabei rauskommt. Was spricht gegen Ansible? Es ist definitiv nicht schnell. Parallelverarbeitung geht so. Und es läuft halt effektiv doch alles über SSH.
02:03
Und man muss Jaml mögen und schreiben können. Weil alles in Ansible ist eigentlich in Jaml-Files. Dann wollte ich jetzt mal kurz über die Basics drüber gehen. Was hat man so für verschiedene Dateien? Wofür braucht man die?
02:24
Das Erste ist die Ordner-Struktur. Man hat so seine Ansible-Config. Irgendwo sind noch gehashte Credentials. Dann hat man eventuell Variablen, die für komplette Gruppen vonnöten sind.
02:41
Dann hat man sein Inventory-File. Playbooks, das sind dann geplante Abläufe von Rollen. Und dann hat man seine Rollen. Die Rollen haben halt alle Namen, haben verschiedene Unterordner drinnen.
03:01
Handlers, Tasks, Templates und Vars. Als erstes gehen wir mal auf die Ansible-CFG ein. Das ist tatsächlich ein simples Config-File, in dem verschiedene globale Konfigurationen gesetzt wird. Wo packe ich meinen Fact-Cache hin?
03:21
Wie lange ist der Faktencache gültig? Wenn ich Sachen mit Ansible Vault verschlüssel, in welcher Datei liegt das Passwort? Das sollte lang und komplex sein. Welchen Ordner soll Ansible auf dem Remote-Server verwenden für temporäre Dateien?
03:41
Das gleiche nochmal für Local. Sowas steht halt in der Ansible-CFG drinnen. Das Inventory. Steht halt mein Inventar drinnen. Meine Server mit diversen Hosts. Mein Root-Server, Raspberry Pi, Arbeitsserver.
04:03
Einfach nur Informationen zu den Hosts. Welche IP-Adressen haben sie? Welcher Ansible-User soll verwendet werden? Und weil ich tatsächlich noch SNMP mitkonfigure, bei den meisten Sachen steht dann auch noch eine SNMP-Location mit drin.
04:22
Wo ist dieser Server? Bei Raspberry Pi ist ganz sinnvoll. Man verliert sie eventuell sonst im Haus. Das ist ein Standard-Playbook. Das ist tatsächlich das Playbook, was ich auf meinen Hosts normalerweise als allererstes immer ausrolle.
04:43
Soll auf allen Hosts eigentlich immer laufen. Soll sich immer die aktuellen Fakten holen. Welche IP-Adressen, Netzwerk-Interfaces, konfigurierte Firewall-Regeln und so weiter. Soll als Remote-User Root verwenden.
05:03
Dann bei den Variablen soll er als User meinen Nutzernamen noch nehmen und dann vier verschiedene Rollen ausführen. Pakete, Datetime, Hostname-Konfiguration
05:23
und mein Nutzerprofil hinlegen. Und ja, dann gehen wir direkt mal auf die Rolle User. Eine README-Datei zu haben ist nett, aber tatsächlich von Ansible nicht gefordert. In den Defaults stehen so Sachen drin,
05:42
halt Defaults, die man dann in den Variablen theoretisch überschreiben kann, aber nicht muss. Files sind einfache Dateien, die ich so wie sie sind auf dem Host haben will. Handlers sind kleine Anweisungen, wie z.B. wenn die Rolle durchgelaufen ist,
06:01
starte den SSHD einmal neu oder wenn irgendein Web-Server konfiguriert wurde, starte den Web-Server neu. In den Tasks stehen dann die Hauptaufgaben und im Ordner Vars stehen dann die ganzen Variablen drinne mit den Werten, die sie darstellen sollen.
06:22
Das sind halt dann einfach nur Defaults. Wie gesagt, Files, Dateien, die man nicht templatet hat, sondern die eins zu eins, wie sie auf dem PC lagen, hochgeladen werden sollen. Das sind jetzt Tasks.
06:44
Lege einmal ein Backup vom Sudo-File an. Guck nach, dass ich Sudo machen darf.
07:00
Der SSH-Agent sollte auch via Sudo klappen. Hier wird dann nochmal ein File-Check gemacht und dann am Ende der SSH-Gemin einfach neu gestartet. Das kann man inzwischen auch mit einem Ansible-Modul lösen,
07:21
was dann automatisch ein Sanity-Check macht vom Sudo-File, weil man möchte das hier nicht kaputt machen, dann sperrt man sich aus. Dann der Händler, das ist einfach nur Restart SSH-Demon.
07:43
Das ist jetzt ein einzelner Task. Installiere die Base Software mit tatsächlich sogar einer Schleife. Nehme die Pakete aus der Liste Namen, also aus der Liste Items.
08:04
Gucke, dass deren State vorhanden ist. Wenn er nicht vorhanden ist, installiert Ansible. Wenn er vorhanden ist, kann Ansible das überspringen. Ein etwas anderer Task.
08:20
Hier wird eine Zeile aus einer Datei geändert. Und zwar auch nur, wenn Primate Root Login noch nicht definiert ist. Und hier hat man das Notify. Notify geht dann an den Händler, wenn die Rolle durchgelaufen ist, bitte sagt dem Händler Restart SSH-Demon Bescheid,
08:42
damit der SSH-Demon neu gestartet wird. Variablen. Wir installieren Pakete. Pakete heißen bei unterschiedlichen Distributionen anders. Und wenn ich zum Beispiel das Paket Monitoring Plugins haben will,
09:01
heißt es einmal Monitoring Plugins Basic unter Debian, Nagios Plugins unter Red Hat und Archnet ist einfach nur Monitoring Plugins. Und damit so eine Rolle halt nicht nur auf einer bestimmten Betriebssystem Distribution funktioniert, kann man halt so eine Zuordnung dann mit Variablen machen.
09:26
Dann haben wir auch noch Variablen, die wir eventuell nicht so ohne weiteres in einem Git liegen haben wollen, die wir nicht unverschriftlich speichern wollen. Da fährt Ansible das Vault. Das Ganze ist dann AES-256 verschlüsselt.
09:44
Das hier ist tatsächlich kein echtes Passwort und keine echten Zugangsdaten, sondern einfach nur von mir gefüllt. Auch wenn AES-256 sicher sein sollte, müssen meine Passwörter nicht in irgendeinem Vortrag zu sehen sein.
10:06
Dann, wie fängt man an? Und hier würde ich jetzt tatsächlich dann in die Live-Demo einsteigen. Man nehme einen Raspberry Pi oder auch mehrere.
10:21
Zum Anfang habe ich mir jetzt überlegt, ein kleines Projekt der Raspberry Pi als DNS-App Blocker mit Pi-Hole. Es wird noch ein NTP Client Server installiert, der sich dann die Zeitsynchronisation von der Physical Station im Bundesanstalt holt
10:41
und theoretisch auch als NTP Server im lokalen Netzwerk dann fungieren kann, dass sich die anderen Clients von dem Raspberry Pi ihre Zeit holen können. Dafür habe ich insgesamt drei Raspberry Pis hier in der Wohnung. Einer ist schon fertig konfiguriert mit Pi-Hole und NTP. Einer ist halb konfiguriert und einer ist noch komplett nackt.
11:03
Hier liegt einer dieser Pis, die anderen beiden, gute Frage. Und dann fangen wir mal an mit der Demo. Ich bin jetzt hier in meinem Ansible-Folder.
11:22
Man sieht mein Inventory, myhost.yml. Man sieht das Playbook, Pi-Hole.yml. Man sieht noch eine andere kleine Rolle, Facts.yml, die einfach nur das Fact Caching neu macht. Und einmal kurz auf das Inventory.
11:42
Ich nehme den Service Pi, Raspberry Pi 4 und Old Pi. Die IP-Adressen einfach konfiguriert im lokalen Netzwerk.
12:05
Und das ist das Playbook, was ich jetzt ausführen möchte. Geht halt auf die Host Service Pi, Pi 4 und Old Pi.
12:21
Und dann probieren wir das doch einfach mal aus. Jetzt holt sich Ansible erstmal die Facts von allen Pys.
12:43
Beziehungsweise nur vom Old Pi noch. Der Raspberry Pi 4 und der Service Pi waren die Facts schon da. Jetzt seht ihr auch auf dem Pi 4 und auf dem Service Pi sind alle Pakete schon installiert gewesen. Deswegen sagt Ansible nur OK.
13:02
Muss nichts mehr getan werden. Und gleich sollte hier changed und dann Old Pi und dann das Paket stehen. Old Pi ist leider ein Raspberry Pi 2.
13:22
Deswegen könnte das etwas dauern.
13:57
Changed Old Pi hat jetzt Wim installiert.
14:11
Ich kann gerade mal daneben noch den alten Raspberry Pi dazu packen. Einfach Übersicht, Edge Top.
14:26
Dann seht ihr hier, effektiv macht Ansible einfach nur SSH.
14:40
Und führt dann ganz viele Python-Module aus. Ok, jetzt zum Beispiel TCP dump installieren.
15:09
Und halt so meine Standardpakete.
15:23
Das erkennen kann. Größe. Hier seht ihr nochmal die einzelnen Pakete.
15:43
Das sind tatsächlich ja sprechende Namen. Und wenn ich jetzt auf die Vars gehe, Main, dann sieht man hier die Zuordnung der einzelnen Paketenamen
16:01
zu den jeweiligen Namen, wie sie in der Distribution im Paket Manager sind. Se-Linux-Python heißt halt unter Debian Python-Se-Linux. Bei Red Hat heißt es lib-Se-Linux-Python. Bei Red Hat heißt Aptitude natürlich leerer String.
16:26
Und wenn hier dann tatsächlich dieser Variablename aufgelöst wird zu einem leeren String, gibt es dieses Feld einfach nicht und Ansible überspringt das. Das ist ganz praktisch, wenn man mehrere Betriebssysteme macht.
16:45
Beziehungsweise mehrere Linungsdistributionen. Hier als nächster Task wird LLDP installiert.
17:06
Einfach damit man die Hosts im Rechenzentrum, wenn man noch physikalische Hardware hat, einfacher finden kann. Das sieht man auch wieder. Auf dem Oldpy war das noch nicht installiert.
17:21
Jetzt kommt die Benutzerkonfiguration, dass man sich später mit seinem SSH-Key anmelden kann. Ihr seht auch, das war auf dem Py4 und dem Servicepy schon erledigt. Auf dem Oldpy noch nicht. Der Oldpy war tatsächlich komplett leer.
17:47
Jetzt der nächste Task ist tatsächlich ein neues Playbook, eine neue Rolle. Nämlich die Netzwerkonfig. Es wäre ja sinnvoll für PyHold, wenn man eine Fixed IP hat.
18:07
Deswegen habe ich da dann gesagt, ich mache IP-Konfig. Ich bin großer Freund von Jaml. Deswegen habe ich mir dann sogar Netplan von Canonical geholt.
18:25
Das wird erst mal installiert. Dann wird diese schöne Netplan-Konfig für das Ethernet-Interface gemacht. Es wird Ethernet 0.
18:40
Der Raspberry Pi hat hier nur einen Plananschluss, wird konfiguriert. Aus dem Ansible-Fact-Cache wird sich die Default-IPv4-Adresse geholt. Ansible hat diesen Fact-Cache. Das kann ich euch auch zeigen. Nehmen wir dafür den Py4.
19:03
Hier hat man jetzt in einem JSON-Objekt Ansible-Default-IPv4. Das hat sich Ansible vorher schon geholt. Dann können wir es hier in der Netzwerkonfiguration, um das Ganze fix zu machen, auch wieder verwenden.
19:24
Jetzt konfiguriert man die statische IPv4-Adresse, V6-Adresse, Gateways, trägt DNS-Server ein. Nachdem dann die Template da ist, das muss eigentlich andersrum sein,
19:50
erst mal Netplan anwenden. Vergesst das. Es muss erst mal den Networking-Service neu starten.
20:01
Raspbian hat das kleine Problem, solange die Datei-ETC-System, die Network-99-Default-Link existiert. Die ist tatsächlich leer. Aber wenn sie existiert, möchte Netplan nicht. Deswegen löschen wir die erst mal. Blacklisten tatsächlich, falls vorhanden, Wi-Fi und Bluetooth-Träger,
20:23
damit die uns in der Netzwerkonfiguration nicht dazwischen funken. Und am Ende wenden wir die Netplan-Template an.
20:43
Und hier seht ihr dann, wie Ansible aus der schönen YAML-Template die Einstellungen befüllt hat. Die IP-Adresse V4, IP-Adresse V6.
21:03
Netplan soll diese Konfiguration machen, wenn die MAC-Adresse des Ethernet-Adapters ist.
21:22
Und ja, wie ihr seht, hat es die Konfiguration sauber angewendet. Das ist jetzt tatsächlich ein längerer Task, sowohl für den Pi 4 als auch für den Raspberry Pi 2.
21:47
Nämlich einmal den apt-package-cache komplett updaten. Bin mal gespannt, ob der Raspberry Pi 4 da Performance-Vorteile hat gegenüber dem Pi 2.
22:05
Aber das ist dann auch fast schon einer der letzten Steps, die etwas länger dauern.
22:28
Und danach sollte es beim Service-Pi sehr schnell gehen, weil Pi-Hole als DNS-Adblocker schon installiert ist. Bei den anderen beiden könnte es ein bisschen länger dauern.
22:43
Und zwar habe ich dafür hier noch einen kleinen Check drinnen, damit diese Rolle auch tatsächlich impotent ist. Guckt diese Rolle, ob das Binary von Pi-Hole schon existiert und registriert das Resultat,
23:03
dass wir das als Bedingung benutzen können für die späteren Tasks. Ansonsten würde er, weil wir hier eine Shell-Exec haben und Ansible das halt nicht testen kann,
23:21
ob dieser Bash-Befehl schon jemals ausgeführt wurde bzw. dieses Shell-Script schon jemals ausgeführt wurde. Würde er es sonst jedes Mal machen und die Installation jedes Mal wiederholen, ist so ein bisschen unpraktisch, weil man sich eventuell dann die Config von Pi-Hole damit zerschießt.
23:41
Und dann hat man kein DNS-Server mehr. Deswegen wird hier halt geguckt, existiert das Pi-Hole Binary. Wenn nein, gehe in die Defaults, Pi-Hole Installer URL, leite diese Datei herunter und mache sie ausführbar.
24:27
Jetzt haben wir erst mal noch, ich hoffe, nur noch eine Minute, bis der Pi 2 fertig ist. Ich hätte ein Pi 4 holen sollen dafür.
25:16
So ein Raspberry Pi 2 ist dann doch sehr langsam im Vergleich zu einem Pi 3 oder 4.
26:20
Ansonsten, wo kann ich noch drauf eingehen? Ach ja, es gibt tatsächlich momentan noch ein kleines Problem. Der Pi-Hole Installer hat einen Bug im Moment, nämlich das Unattended Setup funktioniert nicht so ganz. Im letzten Schritt möchte es dann doch eine Fullscreen Message weggeklickt haben.
26:44
Die wird mit dem in Linux integrierten Tool Wiptail generiert. Und da ist dann halt das Problem, Ansible kann die Meldung nicht erkennen und sie deswegen auch nicht wegklicken. Und dann würde das Setup quasi immer weiterlaufen und nichts tun.
27:08
Deswegen nehmen wir hier die Wiptail-Binary einfach weg, damit dann kein Command-Not-Found-Error kommt.
27:25
Legen wir dem Installer einfach nur Echo dahin, damit es den Output irgendwo hinpipen kann, wohin es irrelevant ist. Und ja, danach erstellen wir einfach die Pi-Hole-Config, auch wieder aus einer Template.
27:46
Hier sind dann sämtliche Konfigurationseinstellungen. Welches Network-Interface soll Pi-Hole nehmen? IP-Adressen? Soll Query-Logging gemacht werden? Soll das Web-Interface installiert werden?
28:08
Privacy Mode? DNS-Server? Möchte ich DNS-Sac haben? Das meiste steht halt in default. In den Variablen steht tatsächlich nur meine Mail-Adresse drin im Moment, weil ich sonst die kompletten Defaults übernehme.
28:23
Man könnte aber auch dann sagen, Pi-Hole DNS-Sac gleich true in vars. Dann würden die Defaults überschrieben werden. Und es würde die spezifischere vars.yml genommen werden.
28:45
Und ja, ihr seht, hier, das war noch Check that some file conf exists. Das ist von mir unbedingt geworden in Check if Pi-Hole binary exists. Ist einfach nur, stat existiert die Datei.
29:04
Und ihr seht, weil sie auf meinem ServicePy schon existiert, überspringt er die Tasks, die für die Installation von Pi-Hole nötig sind. Dadurch ist es einfach gewährleistet, dass ihr jetzt Pi-Hole nicht nochmal installiert.
29:21
Und mir dann sämtliche schon erstellte Config überschreibt. Und ja, jetzt installiert hier Pi-Hole einfach schön alle Pakete, die es braucht.
29:44
Die kommen dann tatsächlich aus dem Installer-Script. Pi-Hole automated basic install. Ist halt ein langes Bash-Script, was da runtergeladen wurde.
30:07
Und dieses Script wird dann halt ausgeführt und hat als Variablen einfach diese Template übergeben bekommen. Und wie die dann auf dem Host aussieht, kann ich euch auch schnell zeigen.
30:24
Wie ihr seht, Ansible hat dann Sachen, wo Variablen als leer definiert wurden, einfach auch leer gelassen.
30:52
Api-exclude-clients, exclude-domains. Seht ihr auch hier, die Variablen sind einfach leer.
31:01
Sind jetzt auch dann in der Config-Datei leer. Welches Theme, welche beiden DNS-Server eingetragen werden sollen.
31:28
Ja, holt sich gerade das Binary von GitHub.
31:43
Hat jetzt den Web-Server gestartet und startet jetzt noch die restlichen Services.
32:07
Jetzt haben wir hier noch dann restore-wiptale. Und jetzt werden alle drei Raspberry Pis einmal neu gestartet. Und dann ist die Demo auch schon durch.
32:23
Und wir haben jetzt tatsächlich drei Hosts, auf denen Pi-Hole als DNS-Adblocker installiert ist, sein sollte. Hier seht ihr auch connection-closed.
33:12
Theoretisch nach einem Reboot müsste Ansible eigentlich nicht nochmal NTP-Demon, Failed-to-Ban und SSH-Demon neu starten.
33:21
Aber ja, ihr seht jetzt Play Recap. Auf dem Old Pi hat er tatsächlich 34 einzelne Tasks ausgeführt, neun geskippt. Auf dem Raspberry Pi 4, auf dem die teilweise Installation gemacht war, hat er 18 Tasks ausgeführt, neun geskippt.
33:42
Und auf dem Service Pi, auf dem eigentlich schon alles fertig installiert war, hat er drei Tasks ausgeführt. Das sind tatsächlich dann Tasks, wo Ansible vorher nicht erkennen kann, ob sie schon mal ausgeführt wurden. Und 17 Tasks wurden insgesamt geskippt.
34:00
Unter anderem halt, wie ihr hier seht, die Pi-Hole-Installation. Dann gehen wir einfach mal auf einen dieser Pis drauf, da ich die Passwörter immer wieder vergesse.
34:48
Das ist tatsächlich der Pi, der vorher schon installiert und konfiguriert war.
35:01
Und das ist der Raspberry Pi 4. Und das hier ist der Raspberry Pi 2. Wie ihr seht, Pi-Hole ist auf allen jetzt installiert und konfiguriert. Und könnt ihr jetzt als DNS-Adblocker für euch zu Hause, euch vor der Verwerbung und der Website der Bild-Zeitung bewahren.
35:31
Dann vielen Dank für eure Aufmerksamkeit. Den Code für die Slides findet ihr auf GitHub. Ich werde das Repository gleich öffentlich schalten.
35:41
Kann ich eigentlich auch jetzt direkt machen. Repository-Settings.
36:22
Das Repository ist jetzt auch öffentlich. Und wie gesagt, die Slides findet ihr inklusive der Links. Wurde ja schon hier im Chat gepostet. Die Slides gibt es entweder unter talk.borchers.ninja oder
36:42
Ihr könnt euch auch den Code für die Slides auf GitHub direkt angucken. Da sind auch dann die Ansible Playbooks drinnen, die rollen. Und dann könnt ihr euch das einfach angucken.