Home → Tech Portfolio → Ansible und Outbound-Proxy: Ein Environment für alle Plays
Ein Ansible-Playbook lässt sich mit wenig Aufwand so schreiben, dass es unabhängig von Betriebssystem, Version und einem vorhandenen HTTP-Proxy funktioniert. Es läuft in der Lab-Umgebung ohne Proxy und im Kundennetz mit Outbound-HTTP-Proxy, ohne dass du es anpassen musst. Eine naheliegende Lösung – das Proxy-Environment an jedem Task zu setzen – skaliert schlecht: Jeder neue Task braucht diese Angabe, und ein vergessener Task fällt erst im Netz mit Proxy auf.
Bisher haben wir in unseren Cheat Sheets Befehle und Tests unter die Lupe genommen. Diesmal geht es nicht um einen Befehl, sondern um ein Ansible-Muster, welches dir im Automatisierungs-Alltag helfen kann. Es gibt viele verschiede Möglichkeiten, ein Proxy-Environment mitzugeben, die wir hier nicht alle beleuchten können. Wir definieren in diesem Beitrag das Environment einmal als Variable und binden sie auf Play-Ebene ein. Ein Environment an jedem einzelnen Task entfällt damit. Einen naheliegenden Weg dorthin schauen wir uns zuerst an, denn er hat seine Tücken.
Ein Ansible-Playbook lässt sich mit wenig Aufwand so schreiben, dass es unabhängig von Betriebssystem, Version und einem vorhandenen HTTP-Proxy funktioniert. Es läuft in der Lab-Umgebung ohne Proxy und im Kundennetz mit Outbound-HTTP-Proxy, ohne dass du es anpassen musst. Eine naheliegende Lösung – das Proxy-Environment an jedem Task zu setzen – skaliert schlecht: Jeder neue Task braucht diese Angabe, und ein vergessener Task fällt erst im Netz mit Proxy auf.
Bisher haben wir in unseren Cheat Sheets Befehle und Tests unter die Lupe genommen. Diesmal geht es nicht um einen Befehl, sondern um ein Ansible-Muster, welches dir im Automatisierungs-Alltag helfen kann. Es gibt viele verschiede Möglichkeiten, ein Proxy-Environment mitzugeben, die wir hier nicht alle beleuchten können. Wir definieren in diesem Beitrag das Environment einmal als Variable und binden sie auf Play-Ebene ein. Ein Environment an jedem einzelnen Task entfällt damit. Einen naheliegenden Weg dorthin schauen wir uns zuerst an, denn er hat seine Tücken.
Der naheliegende erste Schritt ist, das Environment in einem Task zusammenzubauen und als Fact abzulegen:
- name: Mein Play
hosts: all
environment: "{{ proxy_environment | default({}) }}"
tasks:
- name: Build proxy environment
ansible.builtin.set_fact:
proxy_environment: >-
{{
{
'http_proxy': proxy_http | default('', true),
'HTTP_PROXY': proxy_http | default('', true),
'https_proxy': proxy_https | default('', true),
'HTTPS_PROXY': proxy_https | default('', true),
'no_proxy': proxy_no_proxy | default('', true),
'NO_PROXY': proxy_no_proxy | default('', true)
}
| dict2items
| selectattr('value', 'truthy')
| items2dict
}}
default('', true): selectattr('value', 'truthy'):{}. Damit werden keine zusätzlichen Proxy-Umgebungsvariablen gesetzt.default({}) am Play: proxy_environment durch set_fact noch nicht existiert, verhindert default({}) einen Fehler durch eine undefinierte Variable.set_fact und mehrere Plays:set_fact erzeugt eine hostspezifische Variable, die auch in nachfolgenden Plays desselben Playbook-Laufs verfügbar bleibt. Allerdings nur für Hosts, auf denen der Task tatsächlich ausgeführt wurde. Andere Hosts, übersprungene Initialisierungen oder ein direkter Einstieg in ein späteres Play können dazu führen, dass die Variable fehlt. Außerdem wird eine einmal erzeugte Variable nicht automatisch neu berechnet, wenn sich ihre Eingangsvariablen ändern.group_vars/all.yml oder im Play stehen: proxy_environment: >-
{{
{
'http_proxy': proxy_http | default('', true),
'HTTP_PROXY': proxy_http | default('', true),
'https_proxy': proxy_https | default('', true),
'HTTPS_PROXY': proxy_https | default('', true),
'no_proxy': proxy_no_proxy | default('', true),
'NO_PROXY': proxy_no_proxy | default('', true)
}
| dict2items
| selectattr('value', 'truthy')
| items2dict
}} Im Play genügt dann eine Zeile:
- name: Prepare the hosts user
hosts: all
environment: "{{ proxy_environment }}"
tasks:
- name: Ausgehende IP ermitteln (Proxy-Test)
ansible.builtin.uri:
url: https://icanhazip.com
return_content: true
register: proxy_test
- name: Ergebnis anzeigen
ansible.builtin.debug:
msg: "Ausgehende IP: {{ proxy_test.content | trim }}"
proxy_environment bei ihrer Verwendung aus. Die Variable muss daher nicht vorher durch einen Task erzeugt werden. Der Wert ergibt sich aus den zu diesem Zeitpunkt verfügbaren Eingangsvariablen.proxy_environment bereits über die Variablendefinition verfügbar ist, entfällt der set_fact-Task vollständig. Ebenso ist kein default({}) am Play erforderlich, sofern die zentrale Variablendefinition für alle betroffenen Hosts geladen wird.proxy_environment unmittelbar verwenden. Es spielt keine Rolle, ob andere Plays zuvor ausgeführt wurden, ob das Playbook über import_playbook eingebunden oder einzeln gestartet wird.set_fact wird kein einmalig berechnetes Ergebnis gespeichert. Ändern sich die zugrunde liegenden Variablen während des Playbook-Laufs, kann die nächste Auswertung von proxy_environment diese Änderungen berücksichtigen.environment: "{{ proxy_environment }}". Änderungen an der Filterung oder den unterstützten Proxy-Variablen müssen deshalb nicht in mehreren Tasks gepflegt werden.Ein Keyword auf Play-Ebene und eine lazy Variable ersetzen die Task-Lösung. Du pflegst das Proxy-Environment an einer einzigen Stelle, jedes Play bindet es mit einer Zeile ein, und das Playbook läuft mit und ohne Proxy, ohne dass du etwas anpassen musst.
Der Vorteil zeigt sich vor allem im Alltag: Beim nächsten Playbook musst du nicht mehr überlegen, ob der Proxy schon gesetzt wurde. Und wenn du zwischen Lab und Kundennetz wechselst, bleibt die Proxy-Logik dort, wo sie hingehört.
Hier findest du weitere » Cheat Sheets die dir das Leben als Linux-Admin leichter machen.
Share this article
Sie sehen gerade einen Platzhalterinhalt von YouTube. Um auf den eigentlichen Inhalt zuzugreifen, klicken Sie auf die Schaltfläche unten. Bitte beachten Sie, dass dabei Daten an Drittanbieter weitergegeben werden.
Mehr InformationenSie müssen den Inhalt von reCAPTCHA laden, um das Formular abzuschicken. Bitte beachten Sie, dass dabei Daten mit Drittanbietern ausgetauscht werden.
Mehr InformationenSie sehen gerade einen Platzhalterinhalt von Facebook. Um auf den eigentlichen Inhalt zuzugreifen, klicken Sie auf die Schaltfläche unten. Bitte beachten Sie, dass dabei Daten an Drittanbieter weitergegeben werden.
Mehr Informationen