Nein, ich bin nicht auf den Hype als solchen mit aufgesprungen. Es ist nur so… Ansible ist extrem nützlich. Und genau das werde ich anhand eines konkreten Beispiels aufzeigen: Ein Icinga 2 Cluster, vollständig aufgesetzt mit Ansible.
Vorkenntnisse
Wer noch nicht weiß, was zum Geier ein Icinga 2 Cluster und/oder Ansible ist, sollte sich vor dem Weiterlesen entsprechend einarbeiten, am besten im Rahmen einer entsprechenden Schulung in unserem Hause:
- Icinga Schulung (Fundamentals)
- Icinga Advanced
- Ansible Schulung
Alternativ ginge auch das wesentlich mühseligere Selbststudium:
Umgebung
So ein bisschen sensationell soll der Cluster schon sein, aber mit zunehmenden VMs wird es auch zunehmend eng auf meinem Arbeitsgerät. Wie praktisch, dass wir bei NWS einen OpenStack haben, dem ich mal schnell mit Terraform 14 VMs reindrücken kann (2 Master, 2 Satelliten und 10 Agents):
resource "openstack_compute_instance_v2" "aklimov-icinga2" { count = 14 name = "aklimov-icinga2-${count.index}" image_name = "Centos 7" flavor_name = "s1.small" network { name = "${var.tenant_network}" } security_groups = [ "default", "Icinga" ] key_pair = "${var.openstack_keypair}" }
Mit einem kleinen Skript in der Sprache meiner Wahl erstelle ich mir anhand der Terraform-Daten mehr oder weniger automatisch ein Ansible-Inventory (inventory.txt
):
aklimov-icinga2-5 ansible_host=10.77.27.54 ansible_user=centos aklimov-icinga2-4 ansible_host=10.77.27.45 ansible_user=centos aklimov-icinga2-7 ansible_host=10.77.27.51 ansible_user=centos aklimov-icinga2-9 ansible_host=10.77.27.40 ansible_user=centos aklimov-icinga2-12 ansible_host=10.77.27.28 ansible_user=centos aklimov-icinga2-13 ansible_host=10.77.27.18 ansible_user=centos aklimov-icinga2-10 ansible_host=10.77.27.12 ansible_user=centos aklimov-icinga2-1 ansible_host=10.77.27.34 ansible_user=centos aklimov-icinga2-6 ansible_host=10.77.27.20 ansible_user=centos aklimov-icinga2-3 ansible_host=10.77.27.49 ansible_user=centos aklimov-icinga2-11 ansible_host=10.77.27.19 ansible_user=centos aklimov-icinga2-0 ansible_host=10.77.27.21 ansible_user=centos aklimov-icinga2-2 ansible_host=10.77.27.46 ansible_user=centos aklimov-icinga2-8 ansible_host=10.77.27.50 ansible_user=centos
Auf die Plätze, fertig, Ansible!
Zunächst verifiziere ich die Funktionalität der VMs und sammle nebenbei deren öffentliche SSH-Schlüssel ein:
ansible all -i inventory.txt -m ping \ --ssh-common-args='-o StrictHostKeyChecking=no'
Ist das getan, geht es auch schon los mit dem Ansible-Playbook (playbook.yml
):
--- - name: Icinga 2 hosts: all become: yes become_method: sudo tasks: - name: EPEL repo yum: name: epel-release - name: Icinga repo key rpm_key: key: https://packages.icinga.com/icinga.key - name: Icinga repo yum: name: https://packages.icinga.com/epel/icinga-rpm-release-7-latest.noarch.rpm - name: Icinga 2 package yum: name: icinga2 - name: Monitoring plugins yum: name: nagios-plugins-all - name: Icinga 2 service service: name: icinga2 state: started enabled: yes # (...)
Ein paar Repositories, ein paar Pakete – und Icinga ist auch schon einsatzbereit. Fehlt nur noch der eigentliche Cluster:
--- - name: Icinga 2 # (...) - name: Icinga PKI master hosts: aklimov-icinga2-0 become: yes become_method: sudo tasks: - name: Icinga 2 cluster setup shell: > icinga2 node setup --zone master --listen 0.0.0.0,5665 --cn {{ inventory_hostname }} --master --disable-confd; rm -f /var/cache/icinga2/icinga2.vars args: creates: /var/lib/icinga2/certs/ca.crt notify: Restart Icinga 2 - name: /var/cache/icinga2/icinga2.vars shell: icinga2 daemon -C args: creates: /var/cache/icinga2/icinga2.vars - name: Icinga 2 PKI ticket with_inventory_hostnames: - 'all:!{{ inventory_hostname }}' shell: > icinga2 pki ticket --cn {{ item }} >/var/cache/icinga2/{{ item }}.ticket args: creates: '/var/cache/icinga2/{{ item }}.ticket' - name: Fetch Icinga 2 PKI ticket with_inventory_hostnames: - 'all:!{{ inventory_hostname }}' fetch: dest: .tempfiles src: '/var/cache/icinga2/{{ item }}.ticket' - name: Fetch Icinga 2 master cert fetch: dest: .tempfiles src: '/var/lib/icinga2/certs/{{ inventory_hostname }}.crt' handlers: - name: Restart Icinga 2 service: name: icinga2 state: restarted # (...)
Zuerst wird der Knoten eingerichtet, der allen anderen Tickets und später SSL/TLS Zertifikate ausstellt. Dann werden auch schon die Tickets ausgestellt, nachdem /var/cache/icinga2/icinga2.vars
dafür neu erstellt wurde. Diese Tickets und das Zertifikat des Knotens werden danach in das Verzeichnis .tempfiles
heruntergeladen. Die anderen Knoten brauchen diese Dateien, um sich automatisch an den Cluster anzuschließen:
--- - name: Icinga 2 # (...) - name: Icinga PKI master # (...) - name: Icinga cluster nodes hosts: 'all:!aklimov-icinga2-0' become: yes become_method: sudo tasks: - name: Icinga master cert copy: dest: /var/cache/icinga2/trusted.crt owner: icinga group: icinga mode: '0644' src: .tempfiles/aklimov-icinga2-0/var/lib/icinga2/certs/aklimov-icinga2-0.crt - name: Icinga PKI ticket copy: dest: /var/cache/icinga2/my.ticket owner: icinga group: icinga mode: '0600' src: '.tempfiles/aklimov-icinga2-0/var/cache/icinga2/{{ inventory_hostname }}.ticket' - name: Icinga 2 cluster setup shell: > icinga2 node setup --zone {{ inventory_hostname }} --endpoint aklimov-icinga2-0,{{ hostvars['aklimov-icinga2-0'].ansible_all_ipv4_addresses[0] }},5665 --parent_host {{ hostvars['aklimov-icinga2-0'].ansible_all_ipv4_addresses[0] }},5665 --parent_zone master --listen 0.0.0.0,5665 --ticket `cat /var/cache/icinga2/my.ticket` --trustedcert /var/cache/icinga2/trusted.crt --cn {{ inventory_hostname }} --accept-config --accept-commands --disable-confd args: creates: /var/lib/icinga2/certs/ca.crt notify: Restart Icinga 2 handlers: - name: Restart Icinga 2 service: name: icinga2 state: restarted
Und ab dafür:
ansible-playbook -i inventory.txt playbook.yml
Voilà!
(...) PLAY RECAP ******************************************************************************************************* aklimov-icinga2-0 : ok=14 changed=12 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 aklimov-icinga2-1 : ok=12 changed=10 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 aklimov-icinga2-10 : ok=12 changed=10 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 aklimov-icinga2-11 : ok=12 changed=10 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 aklimov-icinga2-12 : ok=12 changed=10 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 aklimov-icinga2-13 : ok=12 changed=10 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 aklimov-icinga2-2 : ok=12 changed=10 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 aklimov-icinga2-3 : ok=12 changed=10 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 aklimov-icinga2-4 : ok=12 changed=10 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 aklimov-icinga2-5 : ok=12 changed=10 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 aklimov-icinga2-6 : ok=12 changed=10 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 aklimov-icinga2-7 : ok=12 changed=10 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 aklimov-icinga2-8 : ok=12 changed=10 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 aklimov-icinga2-9 : ok=12 changed=10 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Jetzt fehlt nur noch die Icinga-Konfiguration. Aber diese überlasse ich keinem geringeren als dem Icinga Director.
Fazit
Was man nicht alles von A bis Z automatisieren kann!
Viel Spaß beim Nachmachen in der NWS Cloud!

Hallo,
interessanter Artikel. Würde evlt. die Möglichkeit bestehen den kompletten Ansible-Teil evtl. in einem Git-Repro anzusehen?