Wie im Blogpost “Puzzle modernisiert mit cloudscale.ch seine IT Infrastruktur” angekündigt, möchten wir es nicht unterlassen auf einige technologische Erneuerungen einzugehen, welche nicht zuletzt dank der Partnerschaft zwischen cloudscale.ch und Puzzle ITC in Ansible Version 2.8 eingeflossen sind.
Ausgangslage
Als wir uns im Team für cloudscale.ch als primärer Cloud Partner entschieden haben, bestand bereits eine gute Integration in Ansible: Das erste Cloudscale Modul für die Bereitstellung von Servern ist bereits seit Version 2.3 in Ansible vorhanden. Später kam die Unterstützung für das Managen von “Floating IPs” und Anfang dieses Jahres “Volumes” dazu.
Während des Aufbaus unserer Cloud Umgebungen kamen unsererseits Anregungen und Feature-Wünsche an die API hinzu, welche offen in Gesprächen mit cloudscale.ch geschärft werden konnten. Die Umsetzung durch cloudscale.ch brachte unter anderem neue oder erweiterte Schnittstellen (API Dokumentation von cloudscale.ch): So kam beispielsweise die neue “Server Groups” API-Ressource für das Handling der “Anti-Affinity” dazu; das bestehende Handling in des Server API wurde als veraltet markiert.
Ändern der Rechenleistung eines Servers
Eine weitere nennenswerte Erweiterung, auf welche wir nachfolgend näher eingehen, erhielt die Server Schnittstelle. Sie erlaubt nun nicht nur auf dem Webportal, sondern auch auf API-Ebene, die Rechenleistung, sprich das “Flavor”, zu ändern.
Um von dieser neuen Funktionalität zu profitieren, musste das zugehörige Ansible-Modul “cloudscale_server” mit einem Update-Mechanismus (PR #52683) versehen werden.
Da ein Wechsel des “Flavors” nur im gestoppten Zustand möglich ist, wurde die Integration so umgesetzt, dass auf gestoppten Servern das gewünschte “Flavor” sofort angewendet wird. Laufende Server wurden jedoch kurzfristig gestoppt und nach der Anpassung wieder gestartet.
Ein Stoppen und Starten eines Servers ist natürlich aus Betreibersicht nicht immer gewünscht und könnte zu einer Downtime eines Services führen oder gar ein SLA verletzen. Aus diesem Grund wurde zusätzlich der Parameter “force” eingeführt, womit man explizit angibt, ob man mit einem Restart des Servers grundsätzlich einverstanden wäre.
Natürlich kann dieser Wert nach gewohnter Ansible-Manier mit einer Variable versehen, in eine Ansible “Role” “defaulted” und in “host_vars” oder “group_vars” pro Server oder Servergruppe überschrieben werden.
Demo
Von einem einfachen Playbook ausgehend, zeigen wir das Verhalten in einem kurzen Screencast.
--- - hosts: localhost gather_facts: no vars: force: no flavor: flex-2 tasks: - name: Provision webservers cloudscale_server: name: webserver-01 image: debian-9 flavor: ”{{ flavor }}” ssh_keys: ”{{ lookup('file', '~/.ssh/id_rsa.pub') }}” force: ”{{ force }}”
Die Kommandozeile bietet mit der Option --extra-vars
die Möglichkeit, Variablen zum Zeitpunkt der Ausführung zu überschreiben. Wir zeigen nun, dass sich der Server nur nach Angabe von force=yes
ändern lässt:
Gruppieren von Servern
Die Möglichkeit eine Anti-Affinity-Gruppierung zu erstellen, bestand bereits im Modul cloudscale_server
.
Ein Manko dieser Schnittstelle war, dass die parallele Provisionierung mehrerer neuer Server in Anti-Affinität zueinander nur umständlich möglich war. Dies, weil mindestens ein Server bereits bestehen musste um dessen UUID für den neuen Server als Parameter anti_affinity_with
übergeben zu können.
Ein Playbook veranschaulicht das Verhalten, bei dem zwei praktisch identische Tasks nötig waren:
--- - hosts: localhost gather_facts: no tasks: - name: start a server cloudscale_server: name: webserver-01 image: debian-9 flavor: flex-4 ssh_keys: ”{{ lookup('file', '~/.ssh/id_rsa.pub') }}” register: server1 - name: Start another server in anti-affinity to the first one cloudscale_server: name: webserver-02 image: debian-9 flavor: flex-4 ssh_keys: ”{{ lookup('file', '~/.ssh/id_rsa.pub') }}” anti_affinity_with: ”{{ server1.uuid }}”
Diese Limitation wurde durch cloudscale.ch mit der neuen API für „Server Groups“ aufgebrochen.
Neu kann mittels Ansibles cloudscale_server_group
eine Gruppe vom Typ “anti-affinity” erstellt und die neuen Server diese Gruppe zugeordnet werden:
--- - hosts: load-balancers gather_facts: no tasks: - name: Ensure load balancer are grouped in anti-affinity cloudscale_server_group: name: load-balancers type: anti-affinity run_once: yes - name: Ensure load balancer node exists cloudscale_server: name: ”{{ inventory_hostname }}” image: debian-9 flavor: flex-4 ssh_keys: ”{{ lookup('file', '~/.ssh/id_rsa.pub') }}” server_groups: load-balancers
Fazit
Wir konnten zwar nicht auf jedes neue Feature der Integration von cloudscale.ch in Ansible Version 2.8 eingehen. Anhand einiger Beispiele versuchten wir aber nicht zuletzt auch aufzuzeigen, dass eine Partnerschaft zweier IT-Firmen auch positive Auswirkungen auf Opensource-Projekte, wie in unserem Fall Ansible, haben kann.