Übung: Ansible

Hello Ansible

Ziel der Übung ist es, eine neue virtuelle Maschine zu erstellen, in der das Programm htop installiert ist. Statt manuell zu installieren, können Sie ein einfaches Ansible Playbook verwenden. Als Infrastruktur-Management nutzen Sie wieder Vagrant. Einer der von Vagrant unterstützten Provisioner ist Ansible, so dass Sie sich in der Übung ganz auf das Ansible Playbook konzentrieren können.

Source Code

Vagrant.configure('2') do |config|
  config.vm.box = "gyptazy/ubuntu22.04-arm64"

  # Install Ansible on the guest
  config.vm.provision 'shell', inline: 'apt update && apt -y install ansible'

  config.vm.provision 'ansible_local' do |ansible|
    ansible.playbook = 'playbook.yml'
  end
end

Anmerkung:

Die folgende Zeile ist nötig, weil die VM (Vagrant Box), mit der wir diese Übung absolvieren, kein Python installiert hat:

config.vm.provision 'shell', inline: '...'

Dieses Bootstrap-Problem lässt sich nicht mit Ansible lösen, weil dafür ja zunächst Python nötig wäre. Vagrant ermöglicht aber auch Provisionierung mit anderen Techniken. Hier benutzen wir den shell-Provisioner, um vor dem Provisionieren mit Ansible den notwendigen Python-Interpreter zu deployen.

Das dazugehörige Playbook sieht so aus:

---
- hosts: all
  become: true
  tasks:
  - name: tree ist installiert
    apt:
      name: tree 
      update_cache: yes

Anleitung

  1. Erstellen Sie ein neues Verzeichnis für dieses Lab, z.B. mit mkdir -p ~/workspace/webservices/ansible
  2. Starten Sie eine Shell und wechseln Sie in das eben erstellte Verzeichnis, z.B. mit cd ~/workspace/webservices/ansible
  3. Legen Sie eine neue Datei Vagrantfile an und kopieren Sie den obigen Inhalt hinein.
  4. Legen Sie eine neue Datei playbook.yml an und kopieren Sie den entsprechenden Inhalt hinein.
  5. Starten Sie die VM mit vagrant up. Das Playbook und die darin enthaltenen Anweisung werden ausgeführt.

    Prüfen Sie die Ausgabe. Eine der letzten Zeilen der Ausgabe zeigt eine kurze Rückschau auf den Ablauf (play recap). Hier ist insbesondere die Anzahl der Tasks, die zu Veränderungen geführt haben (changed=1), interessant:

    PLAY RECAP *********************************************************************
    default                    : ok=2    changed=1    unreachable=0    failed=0
    
  6. Überprüfen Sie den Status mit vagrant status. Sie sollten in etwa folgende Ausgabe sehen:

    Current machine states:
    
    default                   running (virtualbox)
    
  7. Führen Sie das Playbook erneut mit vagrant provision aus und beobachten Sie, dass Rückschau auf den Ablauf (play recap) die Anzahl der Tasks, die zu Veränderungen geführt haben, jetzt mit changed=0 anzeigt, d.h. die VM war bereits in exakt dem Zustand, den das Playbook beschreibt. dass das Programm tree nicht erneut installiert wurde, ist eine entscheidende Folge der Idempotenz von Playbooks.

    PLAY RECAP *********************************************************************
    default                    : ok=2    changed=0    unreachable=0    failed=0
    
  8. Prüfen Sie, ob die Installation erfolgreich war, indem Sie sich per vagrant ssh in die VM einloggen und dann tree ausführen.

Fragen zur Kontrolle

  1. Wie viele Tasks kann ein Playbook enthalten?

  2. Woran erkennen Sie, ob ein Task eine Änderung des Zustandes der VM ausgelöst hat?

Fehlermeldungen

  • fatal: [default]: FAILED! => {"changed": false, "failed": true, "module_stderr": "Shared connection to 127.0.0.1 closed.\\r\\n", "module_stdout": "/bin/sh: /usr/bin/python: not found\\r\\n", "msg": "MODULE FAILURE", "rc": 0}

    Diese Fehlermeldung erscheint, wenn Ansible auf der Zielmaschine keinen Python-Interpreter finden konnte. Stellen Sie sicher, dass beim ersten Start der VM folgende Zeile im Vagrantfile aktiv ist (nicht auskommentiert):

    config.vm.provision 'shell', inline: '...'
    
  • Dateien in /vagrant nicht aktuell? Rufen Sie vagrant rsync auf, um eine Synchronisation zu erzwingen.

Statische Website

In dieser Übung bauen Sie das Playbook aus, um eine statische Website auf einer VM zu deployen. Dafür sind die folgenden Schritte nötig:

  1. Web Server installieren
  2. HTML-Dateien kopieren

Da die VM aus dem vorigen Beispiel bereits existiert, müssen Sie nach einer Änderung am Playbook lediglich vagrant provision aufrufen, um das Playbook erneut auszuführen.

Source Code

Vagrantfile:

Vagrant.configure('2') do |config|
  config.vm.box = "gyptazy/ubuntu22.04-arm64"

  # Install Ansible on the guest
  config.vm.provision 'shell', inline: 'apt update && apt -y install ansible'

  config.vm.network 'forwarded_port', guest: 80, host: 8080

  config.vm.provision 'ansible_local' do |ansible|
    ansible.playbook = 'playbook.yml'
  end
end

Beachten Sie, dass wir eine neue Zeile in der Konfiguration eingefügt haben, um den Port 80 (Web Server) von der VM auf den Host weiterzuleiten. Außerhalb dieser Übung ist das nicht nötig, da die VM meist eine eigene IP-Adresse erhält und darüber erreichbar ist.

nginx Konfiguration default (Datei neben playbook.yml):

server {
  listen 80 default_server;
  listen [::]:80 default_server;
  root /usr/share/nginx/html;
}

Das dazugehörige Playbook sieht so aus:

---
- hosts: all
  become: true
  tasks:
    - name: Web Server ist installiert
      apt:
        name: nginx
    - name: Konfiguration ist aktuell
      copy:
        src: default
        dest: /etc/nginx/sites-available/
      notify:
        - Webserver-Konfiguration geändert
    - name: Web Server läuft und wird beim Booten gestartet
      service:
        name: nginx
        state: started
        enabled: yes
    - name: Document root ist vorhanden
      copy:
        src: html
        dest: /usr/share/nginx/
  handlers:
    - name: Webserver-Konfiguration geändert
      service:
        name: nginx
        state: restarted

Überlegen Sie, woher die HTML-Datei im obigen Beispiel kommt und legen sie den entsprechenden lokalen Ordner an.

Anleitung

  1. Modifizieren Sie Vagrantfile und playbook.yml wie oben angegeben.
  2. Legen Sie die HTML-Datei an.
  3. Führen Sie das Deployment mit vagrant provision aus.
  4. Gehen Sie in einem Web Browser zur Adresse http://localhost:8080/. Es sollte eine Website gezeigt werden.
  5. Überprüfen Sie das access.log des Web Servers:
    • Melden Sie sich mit vagrant ssh an der VM an
    • Zeigen Sie das Logfile an: tail -f /var/log/nginx/. Neue Requests im Web Browser sollen jeweils zu einem neuen Eintrag führen.
    • Verlassen Sie tail mit Control-C und die VM mit exit oder Control-D.

Fragen zur Kontrolle

  1. Welche Datei muss geändert werden, um apache statt nginx als Web Server zu verwenden?

  2. Was muss am Playbook verändert werden, damit ein zusätzliches Bild mit in die VM kopiert wird?

Templating

Auf Basis der vorherigen Beispiele können Sie das Playbook jetzt so verändern, dass die HTML-Datei nicht nur kopiert, sondern auch der Inhalt angepasst wird. In der Vorlesung haben wir dazu das Konzept von Variablen und Templates kennengelernt.

Source Code

Vagrantfile:

Vagrant.configure('2') do |config|
  config.vm.box = "gyptazy/ubuntu22.04-arm64"

  # Install Ansible on the guest
  config.vm.provision 'shell', inline: 'apt update && apt -y install ansible'
  config.vm.network 'forwarded_port', guest: 80, host: 8080
  config.vm.provision 'ansible_local' do |ansible|
    ansible.playbook = 'playbook.yml'
  end
end

playbook.yml:

---
- hosts: all
  become: true
  tasks:
    - name: Web Server ist installiert
      apt:
        name: nginx
        update_cache: yes
    - name: Konfiguration ist aktuell
      copy:
        src: default
        dest: /etc/nginx/sites-available/
      notify:
        - Webserver-Konfiguration geändert
    - name: Web Server läuft und wird beim Booten gestartet
      service:
        name: nginx
        state: started
        enabled: yes
    - name: Document root ist vorhanden
      copy:
        src: html
        dest: /usr/share/nginx/
    - name: index.html gerendert
      template:
        src: html/index.html.j2
        dest: /usr/share/nginx/html/index.html
  handlers:
    - name: Webserver-Konfiguration geändert
      service:
        name: nginx
        state: restarted

Anleitung

  1. Modifizieren Sie das vorherige Beispiel so, dass die HTML-Datei nicht kopiert, sondern durch Templating erstellt wird.
  2. Ändern Sie die index.html so, dass in der Fußzeile das Datum des Deployments erscheint. Sie können dazu die Ansible-Variable ansible_date_time.iso8601 verwenden.
  3. Ändern Sie das Playbook, so dass zusätzlich zum Kopieren des HTML-Ordners auch die index.html als Template interpretiert wird.
  4. Führen Sie das Deployment mit vagrant provision aus.
  5. Gehen Sie in einem Web Browser zur Adresse http://localhost:8080/. Der Footer der Website sollte jetzt einen Text analog zu dem folgenden enthalten:

Statische Website gebaut mit Pure.css am 2017-10-07T21:37:02Z

Fragen zur Kontrolle

  1. Wie heißt die Templating-Sprache, die Ansible verwendet?

  2. Welche Schritte sind notwendig, um eine Variable im CSS-File zu verwenden?

Literatur

Aufräumen

  1. Löschen Sie die erstellten VMs und deren virtuelle Festplatten mit dem folgenden Kommando:

    $ vagrant destroy -f
    
  2. Überprüfen Sie, dass keine VM mehr existiert:

    $ vagrant status
    Current machine states:
    
    default                   not created (virtualbox)
    

Sie können die Überprüfung auch in der GUI ausführen; virtualbox sollte keine VMs anzeigen.

Hinweise Linux-Labor

  • Nur dieser Kurs darf VirtualBox im Rahmen der Vorlesung “Web Services” benutzen. Ihre Quota wurde dafür angehoben und wird nach Abschluss des Kurses wieder auf den Standard-Wert zurückfallen.
  • Die virtuellen Festplatten werden sehr groß und sind jederzeit durch Ihren Quellcode reproduzierbar, so dass sie nicht im Backup enthalten sind. Stellen Sie sicher, dass Sie ihren Quellcode (Vagrantfile etc.) auf Ihrem persönlichen Laufwerk halten, wo es dem Backup unterliegt.
  • Die virtuellen Festplatten müssen nach Abschluss des Kurses gelöscht werden.
  • In VirtualBox dürfen nur NAT-Netzwerkkarten benutzt werden. Vagrant macht das von sich aus; diese Einstellung darf nicht verändert werden.
letzte Änderung: 12. Dezember 2023