2.1. Einleitung

Dieses Kapitel bietet einen Überblick über Ansible, ein Open-Source-Tool für die Automatisierung von IT-Infrastrukturen und Anwendungen. Es wurde 2012 von Michael DeHaan entwickelt und wird seither von der Community gepflegt. Mit Ansible lassen sich komplexe IT-Verwaltungsaufgaben automatisieren, um Zeit und Ressourcen zu sparen und Fehler zu minimieren. Mit Ansible können IT-Teams schnell und einfach Konfigurationsänderungen, Anwendungsimplementierungen und Infrastruktur-Upgrades auf Tausenden von Servern gleichzeitig durchführen.

Ansible unterscheidet sich von anderen Automatisierungstools durch seine Einfachheit und Agentenlosigkeit. Im Gegensatz zu anderen Tools muss für Ansible keine Software auf den zu verwaltenden Systemen installiert werden. Stattdessen verwendet Ansible SSH, um mit remote Systemen zu kommunizieren. Dadurch braucht es für Ansible selber keine eigenen Softwarepakete auf den Remote-Systemen, sondern kann direkt vom “Controller”-System (z.B. dem des Systemadministrators) verwendet werden.

2.1.1. Motivation

Als Team haben wir beschlossen, uns mit Ansible zu beschäftigen, weil wir glauben, dass es ein wichtiges Werkzeug für zukünftige IT-Administratoren ist. In der heutigen Welt müssen Unternehmen in der Lage sein, ihre IT-Infrastruktur schnell und flexibel an veränderte Anforderungen anzupassen. Ansible kann dabei helfen, indem es die Bereitstellung von Anwendungen und Infrastruktur-Upgrades beschleunigt und automatisiert.

2.2. Grundlagen

2.2.1. Was ist Ein Automatisierungstool für die Infrastruktur?

Ein Automatisierungstool für IT-Infrastruktur ist eine Software, die es IT-Teams ermöglicht, Aufgaben und Prozesse zu automatisieren und zu orchestrieren, die für die Verwaltung von IT-Infrastrukturen erforderlich sind. Diese Tools bieten eine Möglichkeit, Prozesse zu standardisieren und zu automatisieren, um Zeit und Kosten zu sparen und Fehler zu minimieren.

Die Automatisierungstools unterscheiden sich vor allem in ihrer Struktur, d. h. darin, ob sie einen Agents auf den Systemen benötigen oder nicht. Einige Tools, wie Puppet und Chef, benötigen einen “Agent”, der auf dem Zielserver-/system installiert wird und dann mit dem zentralen “Konfigurationsserver” spricht, um Konfigurationen und Änderungen abzurufen und auf dem lokale Systme durchzuführen. Andere Tools, wie Ansible, sind agentenlos und verwenden SSH-Verbindungen, um Änderungen auf den Servern vorzunehmen.

2.2.2. Architektur

Ansibles Funktionsweise basiert auf der Client-Server-Architektur. Das bedeutet, dass Ansible keine “Agent” auf den Zielservern benötigt und, wie oben beschrieben, direkt mit den Zielsystemen über das SSH-Protokoll kommuniziert. Deshalb ist die grundlegende Architektur relativ einfach. Es existiert ein zentraler Server/Computer, auch Control Node genannt, der alle Konfigurationen, Playbooks und Module beherbergt. Auf dem Control Node läuft in der Regel ein Linux-basiertes Betriebssystem (muss aber nicht) auf dem Ansible installiert ist.

Die Konfigurations- und Automatisierungsaufgaben werden in so genannten Playbooks definiert, die in YAML-Syntax gefasst sind. Jedes Playbook besteht aus einer Reihe von Aufgaben, die in Form von Modulen definiert sind. Module sind unabhängige Codeeinheiten, die bestimmte Aufgaben wie das Anlegen von Benutzern, das Installieren von Paketen (z. B. über APT unter Debian) oder das Ändern von Dateien und vieles mehr ausführen können.

In Ansible sind alle Zielsysteme in einem sogenannten Inventar definiert. Das Inventar ist eine einfache Textdatei, die alle Hosts und Gruppen von Hosts enthält, auf die die definierten Aufgaben angewandt werden sollen.

2.2.3. Wichtige Begriffe

  • Control node: Der Rechner, auf dem Ansible installiert ist und auf dem alle Aufgaben und Playbooks ausgeführt werden

  • Module: Ein Modul ist im Grunde ein Befehl oder eine Reihe ähnlicher Ansible-Befehle, die auf der Client-Seite ausgeführt werden

  • Task: Ein Task ist ein Abschnitt, der aus einem einzelnen auszuführenden Vorgang besteht

  • Role: Eine Möglichkeit zur Organisation von Tasks und zugehörigen Dateien, die später in einem Playbook aufgerufen werden

  • Fact: Informationen, die mit der Operation gather-facts vom Client-System aus den globalen Variablen geholt werden

  • Inventory: Datei, die Daten über die Ansible-Client-Server enthält. Wird in späteren Beispielen als hosts-Datei definiert

  • Play: Ausführung eines Playbooks

  • Handler: Task, der aufgerufen wird, wenn ein Notifier vorhanden ist

  • Notifier: Abschnitt, der mit einem Task verbunden ist, der einen Handler aufruft, wenn die Ausgabe geändert wird

  • Tag: Name, der einem Task zugewiesen wird und später verwendet werden kann, um nur diesen speziellen Task oder diese Gruppe von Tasks auszugeben

2.2.4. Ansible vs. Salt-Stack

Ansible und Salt sind zwei der bekanntesten Open-Source-Automatisierungstools für die IT-Infrastruktur. Beide Tools ermöglichen die Automatisierung von Konfigurationen und Prozessen, um Zeit und Ressourcen zu sparen und menschliche Fehler zu minimieren.

Beide Tools verwenden die YAML-Syntax für ihre Konfigurationsdateien und verfügen über eine deklarative Sprache zur Definition von Zuständen und Konfigurationen. Sowohl Ansible als auch Salt unterstützen die Verwaltung mehrerer Betriebssysteme und Cloud-Plattformen und verfügen über eine aktive Community, die ständig neue Module und Plugins kreiert.

Salt bietet zusätzliche Funktionen wie die Möglichkeit, auf Echtzeit-Ereignisse zu reagieren und Response-Strategien zu definieren, um auf der Grundlage von Ereignissen automatisierte Aktionen auszulösen. Ansible unterstützt diese Funktionen in der Standardversion jedoch nicht. Salt bietet außerdem mehr Flexibilität und leistungsstarke Funktionen für komplexe Szenarien, während Ansible einfacher einzurichten und zu verwenden ist und weniger Konfigurationsaufwand erfordert.

Vor allem wegen der Einfachheit und des geringen Aufwands bei der Einrichtung der anfänglichen Infrastruktur setzen wir als Team hauptsächlich auf Ansible, da es perfekt auf unsere Automatisierungsszenarien zugeschnitten ist.

2.3. Vagrant

Für den Test- & Entwicklungsprozess ist es da auch wichtig, eine Umgebung zu haben, in welcher die Ansible Playbooks gestestet werden kann. Dafür setzen wir auf Vagrant.

Vagrant ist eine Open-Source-Software, mit der Entwickler schnell und einfach virtuelle Umgebungen einrichten und verwalten können. Mit Vagrant kann man eine virtuelle Maschine oder einen Container erstellen und konfigurieren, um eine spezielle Umgebung für die Entwicklung oder das Testen einer Anwendung zu schaffen (in unserem Fall das Ansible Playbook). Vagrant vereinfacht den Prozess der Erstellung und Verwaltung virtueller Umgebungen, indem es eine einfache und einheitliche Schnittstelle für die Verwendung verschiedener Virtualisierungstechnologien wie VirtualBox, VMware und Docker bietet.

Wenn es um das Testen von Ansible-Playbooks geht, ist Vagrant ein wertvolles Tool. Da Ansible-Playbooks spezifische Konfigurationen und Einstellungen für das Zielsystem enthalten, kann es schwierig sein, sie auf dem lokalen Rechner zu testen. Mit Vagrant hingegen kann man eine virtuelle Umgebung erstellen, die der Umgebung ähnelt, in der man die Playbooks ausführen möchte. In dieser virtuellen Umgebung kann man dann die Playbooks testen, um sicherzustellen, dass sie wie erwartet funktionieren, bevor man sie auf die Zielsystemumgebung anwendet. So lassen sich potenzielle Probleme im Voraus erkennen und die Anwendung fehlerhafter Playbooks auf Produktivumgebungen verhindern.

2.4. Ansible nutzen

Ansible muss als erstes auf dem gewünschten Zielsystem installiert werden.

Dafür richtet man sich am besten nach dem Guide von Ansible selbst.

2.4.1. Die Basics - Ad-hoc Befehle

Eine der einfachsten Möglichkeiten, Ansible zu nutzen, ist die Verwendung von Ad-hoc-Befehlen. Diese können verwendet werden, wenn bestimmte Befehle auf einem Server oder einer Gruppe von Servern ausgeführt werden sollen. Ad-hoc-Befehle werden nicht zur späteren Verwendung gespeichert, sondern sind eine schnelle Möglichkeit, mit den gewünschten Servern zu interagieren.

$ ansible -i hosts all -m ping
host1 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
host2 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

Wenn wir wollen, können wir das Kommando auch einen Zielhost limitieren.

$ ansible -i hosts all -m ping --limit host1
host1 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

2.4.1.1. Installationsstatus eines Pakets überprüfen

Wenn wir ein Paket installieren wollen (hier auf einem CentOS basierten System), können wir das mit Hilfe des folgenden Kommandos durchführen, indem wir den state des Pakets abrufen.

$ ansible -i hosts all -m yum -a 'name=ncdu state=present'
host1 | SUCCESS => {
    "changed": true,
    "msg": "",
    "rc": 0,
    "results": [
"Loaded plugins: fastestmirror\nLoading mirror speeds from cached hostfile\n * base: mirror.netsite.dk\n * elrepo: mirrors.xservers.ro\n * epel: fedora.mirrors.telekom.ro\n * extras: centos.mirrors.telekom.ro\n * remi-php70: remi.schlundtech.de\n * remi-safe: remi.schlundtech.de\n * updates: centos.mirror.iphh.net\nResolving Dependencies\n--> Running transaction check\n---> Package ncdu.x86_64 0:1.14-1.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package         Arch              Version                Repository       Size\n================================================================================\nInstalling:\n ncdu            x86_64            1.14-1.el7             epel             51 k\n\nTransaction Summary\n================================================================================\nInstall  1 Package\n\nTotal download size: 51 k\nInstalled size: 87 k\nDownloading packages:\nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Installing : ncdu-1.14-1.el7.x86_64                                       1/1 \n  Verifying  : ncdu-1.14-1.el7.x86_64                                       1/1 \n\nInstalled:\n  ncdu.x86_64 0:1.14-1.el7                                                      \n\nComplete!\n"
    ]
}

2.4.2. Versuchsdurchführung

2.4.2.1. Vagrant Installation

Zuerst installieren wir Vagrant auf unserem Control Node. In unserem Beispiel haben wir nur Distributionen wie Debian und Ubuntu verwendet.

$ wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg
$ echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
$ sudo apt update && sudo apt install vagrant -y

Nun legen wir ein neues Verzeichnis an, in dem wir die Konfiguration für die zu erstellenden Maschinen speichern.

$ mkdir test-vm
$ cd test-vm

2.4.2.2. Erstellen einer VM mithilfe von Vagrant

In dem soeben erstellten Verzeichnis erstellen wir nun die Konfigurationsdatei für die gewünschte virtuelle Maschine. Allerdings verwendet man dafür “vorgefertigte” Images, die im Vagrant-Katalog zu finden sind. Hier kann auch erkennen für welche Virtualiserungslösungen die einzelnen Images verfügbar sind.

Die Testmaschine haben wir auf der Grundlage von Jammy erzeugt. Um dies zu gewährleisten initialiseren wir unsere Vagrantfile mit der herausgesuchten Box.

$ vagrant init bento/ubuntu-22.04 

Außerdem müssen wir noch Virtualiserungsvorraussetzung auf dem System installieren. In unserem Fall war dies VirtualBox.

$ apt-get install virtualbox

Die Maschine kann nach Erstellung des Vagrantfiles und der Installation der Virtualisierungslösung durch folgenden Befehl gestartet werden:

$ vagrant up

Nach Absetzen des Befehles werden automatisch überprüft, ob das Image schon besteht, aktualisiert oder heruntergeladen werden muss. Und dies bei jedem Start der Maschine. Außerdem richtet Vagrant bei der Erstellung den Zugriff per SSH automatisch ein und hinterlegt den bei jeder Instanz neu angelegten Privatkey im selben Verzeichnis. Die SSH-Konfiguration kann auch folgendermaßen abgerufen werden.

$ vagrant ssh-config

Um zu sehen, ob alle Prozesse ordnungsgemäß funktionieren und die Erstellung soweit erfolgreich war, führen wir den folgenden Befehl aus, um den Status der Maschine anzuzeigen.

$ vagrant status 

Eine einfache SSH-Verbindung zum Rechner kann mit dem folgenden Befehl hergestellt werden. Diese Verbindung unterscheidet sich in ihrer Funktionsweise nicht von anderen.

$ vagrant ssh 

Im folgenden sieht man die verwendete Vagrantfile für die Konfiguration der VM.

# -*- mode: ruby -*-
# vi: set ft=ruby :

# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure("2") do |config|
  # The most common configuration options are documented and commented below.
  # For a complete reference, please see the online documentation at
  # https://docs.vagrantup.com.

  # Every Vagrant development environment requires a box. You can search for
  # boxes at https://vagrantcloud.com/search.
  config.vm.box = "bento/ubuntu-22.04"

  # Disable automatic box update checking. If you disable this, then
  # boxes will only be checked for updates when the user runs
  # `vagrant box outdated`. This is not recommended.
  # config.vm.box_check_update = false

  # Create a forwarded port mapping which allows access to a specific port
  # within the machine from a port on the host machine. In the example below,
  # accessing "localhost:8080" will access port 80 on the guest machine.
  # NOTE: This will enable public access to the opened port
  # config.vm.network "forwarded_port", guest: 80, host: 8080

  # Create a forwarded port mapping which allows access to a specific port
  # within the machine from a port on the host machine and only allow access
  # via 127.0.0.1 to disable public access
  # config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"

  # Create a private network, which allows host-only access to the machine
  # using a specific IP.
  # config.vm.network "private_network", ip: "10.69.2.200"

  # Create a public network, which generally matched to bridged network.
  # Bridged networks make the machine appear as another physical device on
  # your network.
  config.vm.network "public_network", ip: "10.69.2.200", :bridge => "ens33"

  # Share an additional folder to the guest VM. The first argument is
  # the path on the host to the actual folder. The second argument is
  # the path on the guest to mount the folder. And the optional third
  # argument is a set of non-required options.
  # config.vm.synced_folder "../data", "/vagrant_data"

  # Provider-specific configuration so you can fine-tune various
  # backing providers for Vagrant. These expose provider-specific options.
  # Example for VirtualBox:
  #
  # config.vm.provider "virtualbox" do |vb|
  #   # Display the VirtualBox GUI when booting the machine
  #   vb.gui = true
  #
  #   # Customize the amount of memory on the VM:
  #   vb.memory = "1024"
  # end
  #
  # View the documentation for the provider you are using for more
  # information on available options.

  # Enable provisioning with a shell script. Additional provisioners such as
  # Ansible, Chef, Docker, Puppet and Salt are also available. Please see the
  # documentation for more information about their specific syntax and use.
  # config.vm.provision "shell", inline: <<-SHELL
  #   apt-get update
  #   apt-get install -y apache2
  # SHELL
end

Da die Maschine nicht nur zum Testen von Ansible gebaut wurde, sondern auch für die Anwendung, die wir automatisch darauf installieren wollen, wird der Maschine eine IP-Adresse innerhalb des Netzwerks zugewiesen, von der die Anwendung später Daten abrufen wird.

2.4.2.3. Ansible Installation

Für die Installation von Ansible haben wir das Python-Tool pip verwendet. Die aktuell installierte Version von pip wird wie folgt überprüft.

$ python3 -m pip -V

Sollte pip noch nicht vorhanden sein, kann dies einfach auf dem System nachinstalliert werden.

$ curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
$ python3 get-pip.py --user

Jetzt fehlt nur noch, Ansible auf dem System zu installieren.

$ python3 -m pip install --user ansible

Falls benötigt, kann Ansible auch aktualisiert werden. Das ist vor allem bei neuen Features & Sicherheitsupdates wichtig.

$ python3 -m pip install --upgrade --user ansible

Nach der Installation sollte man Prüfen, ob Ansible ausführbar ist. Es könnte allerdings auch von Nöten sein die Umgebungsvariablen erneut abzurufen/neu zu laden, bevor man mit Ansible loslegen kann.

$ ansible --version

Jetzt können wir mit der Automatisierung unserer Installation beginnen. Die Anwendung, die vollautomatisch installiert und konfiguriert werden soll, ist eine Monitoring-Anwendung namens checkmk.

2.4.2.4. Erstellen einer Rolle

Um die Automatisierungen besser aufzuteilen, haben wir uns für die Verwendung von Rollen entschieden, da die Automatisierung auch nach dem DVA-Seminar weiter verwedndet werden soll. Wir legen eine neue Rolle wie folgt an:

$ ansible-galaxy init checkmkinstaller
  • defaults – Enthält Standardwerte für Variablen der Rolle. Hier werden einige sinnvolle Standardvariablen definiert, die jedoch die niedrigste Priorität haben und normalerweise von anderen Methoden zur Anpassung der Rolle überschrieben werden.

  • files – Enthält statische und benutzerdefinierte Dateien, die die Rolle zur Ausführung verschiedener Aufgaben verwendet.

  • handlers – Eine Reihe von Handlern, die durch Aufgaben der Rolle ausgelöst werden.

  • meta – Enthält Metadaten-Informationen über die Rolle, ihre Abhängigkeiten, den Autor, die Lizenz, die verfügbare Plattform usw.

  • tasks – Eine Liste von Aufgaben, die von der Rolle auszuführen sind. Dieser Teil könnte als ähnlich wie der Aufgabenabschnitt eines Playbooks betrachtet werden.

  • templates – Enthält Jinja2 Template Files, die von den Tasks der Rolle verwendet werden.

  • tests – Enthält Konfigurationsdateien für die Rollenprüfung.

  • vars` – Enthält Variablen, die für die Rolle definiert sind. Diese haben in Ansible einen ziemlich hohen Stellenwert.

Schauen wir uns nun die einzelnen YAML-Dateien genauer an:

Die Default Konfiguration muss bei Versionsänderung der Applikation oder Distribution verändert werden. defaults/main.yml

---
# default config for installing checkmk
auto_checkmk_server_source_url: https://download.checkmk.com/checkmk/{{ auto_checkmk_server_version }}/{{ auto_checkmk_server_source }}
auto_checkmk_server_version: 2.2.0b4
distro_version_name: jammy
auto_checkmk_server_source: check-mk-raw-{{ auto_checkmk_server_version }}_0.{{ distro_version_name }}_amd64.deb
auto_checkmk_key_url: https://download.checkmk.com/checkmk/Check_MK-pubkey.gpg
auto_checkmk_server_site: monitoring
...

Hier werden die Tasks definiert, die auf den VMs abgearbeitet werden. tasks/main.yml

---
# tasks for automated configuration
- name: Install packages | APT
  apt:
    name: "{{ auto_checkmk_packages }}"
    state: present
    update_cache: yes
  tags:
    - auto-checkmk-server
- name: Import key | APT_KEY
  apt_key:
    url: "{{ auto_checkmk_key_url }}"
    state: present
  tags:
      - auto-checkmk-server
- name: Check Checkmk file | STAT
  stat:
    path: "/opt/{{ auto_checkmk_server_source }}"
  register: auto_checkmk_server_package
  tags:
    - auto-checkmk-server
- name: Download Checkmk Server | GET_URL 
  get_url:
    dest: /opt
    mode: 0755
    url: "{{ auto_checkmk_server_source_url }}"
  when: not auto_checkmk_server_package.stat.exists
  tags: 
    - auto-checkmk-server
- name: Install Checkmk | APT
  apt:
    deb: "/opt/{{ auto_checkmk_server_source }}"
    state: present
  tags:
    - auto-checkmk-server
- name: Setup OMD | COMMAND
  command: omd setup
  args:
    creates: /opt/omd
  tags:
    - auto-checkmk-server
- name: Create OMD site | COMMAND
  command: omd create {{ auto_checkmk_server_site }}
  args:
    creates: /opt/omd/sites/{{ auto_checkmk_server_site }}
  register: auto_checkmk_server_omd_create
  tags:
    - auto-checkmk-server
- name: Creation Log | COPY
  copy:
    content: "{{ auto_checkmk_server_omd_create }}"
    dest: /opt/omd/sites/{{ auto_checkmk_server_site }}/omd-create.log
    group: "{{ auto_checkmk_server_site }}"
    owner: "{{ auto_checkmk_server_site }}"
    mode: 0600
    force: no
  when: auto_checkmk_server_adminpw is undefined
  tags:
      - auto-checkmk-server
- name: Change OMD site admin password | HTPASSWD
  htpasswd:
   path: /opt/omd/sites/{{ auto_checkmk_server_site }}/etc/htpasswd
   name: cmkadmin
   password: "{{ auto_checkmk_server_adminpw }}"
  become: true
  become_user: "{{ auto_checkmk_server_site }}"
  vars:
    ansible_ssh_pipelining: yes
  when: auto_checkmk_server_adminpw is defined
  tags:
    - auto-check-mk-server
- name: Start OMD site | COMMAND
  command: omd start {{ auto_checkmk_server_site }}
  args:
    creates: /opt/omd/sites/{{ auto_checkmk_server_site }}/tmp/apache/run/apache.pid
  tags:
    - auto-check-mk-server
- name: Start Apache2 | SERVICE
  service:
    name: "{{ auto_checkmk_webservice }}"
    state: started
    enabled: yes
  tags:
    - auto-check-mk-server
...

Die Variablen sind aktuell nur für die verwendete Ubuntu Version definiert. Hier könnten wir allerdings noch verschieden Versionen der Distribution oder sogar verschiedene Distributionen aufführen. Und somit eine Dynamik implementieren. vars/main.yml

  ---
# packages needed on ubuntu systems for checkmk to run
auto_checkmk_packages:
  - apache2
  - apt-utils
  - cron
  - dpkg-sig
  - iproute2
  - libevent-2.1-7
  - libfl2
  - python3-passlib
  - xz-utils
auto_checkmk_webservice: apache2
...

2.4.3. Erstellung des Inventory und des Playbooks

Die über Vagrant erstellte VM kann nun im Inventory aufgenommen werden und der für den Zugriff benötigte SSH-Key als Variable übergeben werden. inventory.ini

 [vms]
10.69.2.200 ansible_ssh_private_key_file=~/test-vm/.vagrant/machines/default/virtualbox/private_key

Nun zum eigentlichen Playbook hier definieren wir welche Hosts aus dem Inventory abgearbeitet werden sollen und können hier auch zusätzlich zu unseren Rollen noch andere Tasks definieren.

playbook.ini

- name: Install Checkmk Server
  hosts: vms
  remote_user: vagrant
  become: yes
  tasks:
   - name: Ping my hosts
     ansible.builtin.ping:
   - name: Print message
     ansible.builtin.debug:
       msg: Hello Prof. Hoegl. This is group 53 speaking.
  roles:
    - checkmkinstaller 

Nach dem Hinzufügen der Playbook-Dateien können wir dieses nun auch testen!

$ ansible-playbook -i inventory.ini playbook.yaml

PLAY [Install Checkmk Server] ****************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************************************************************************************************************
ok: [10.69.2.200]

TASK [checkmkinstaller : Install packages | APT] *********************************************************************************************************************************************************************************************************
ok: [10.69.2.200]

TASK [checkmkinstaller : Import key | APT_KEY] ***********************************************************************************************************************************************************************************************************
ok: [10.69.2.200]

TASK [checkmkinstaller : Check Checkmk file | STAT] ******************************************************************************************************************************************************************************************************
ok: [10.69.2.200]

TASK [checkmkinstaller : Download Checkmk Server | GET_URL] **********************************************************************************************************************************************************************************************
skipping: [10.69.2.200]

TASK [checkmkinstaller : Install Checkmk | APT] **********************************************************************************************************************************************************************************************************
ok: [10.69.2.200]

TASK [checkmkinstaller : Setup OMD | COMMAND] ************************************************************************************************************************************************************************************************************
ok: [10.69.2.200]

TASK [checkmkinstaller : Create OMD site | COMMAND] ******************************************************************************************************************************************************************************************************
ok: [10.69.2.200]

TASK [checkmkinstaller : Creation Log | COPY] ************************************************************************************************************************************************************************************************************
ok: [10.69.2.200]

TASK [checkmkinstaller : Change OMD site admin password | HTPASSWD] **************************************************************************************************************************************************************************************
skipping: [10.69.2.200]

TASK [checkmkinstaller : Start OMD site | COMMAND] *******************************************************************************************************************************************************************************************************
ok: [10.69.2.200]

TASK [checkmkinstaller : Start Apache2 | SERVICE] ********************************************************************************************************************************************************************************************************
ok: [10.69.2.200]

TASK [Ping my hosts] *************************************************************************************************************************************************************************************************************************************
ok: [10.69.2.200]

TASK [Print message] *************************************************************************************************************************************************************************************************************************************
ok: [10.69.2.200] => {
    "msg": "Hello Prof. Högl. This is group 53 speaking."
}

PLAY RECAP ***********************************************************************************************************************************************************************************************************************************************
10.69.2.200                : ok=12   changed=0    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0  

2.4.4. Literaturverzeichnis