Finde uns auf Social Media

Arbeit als Cloud Consultant

Ansible Tower – Implementierung einer dynamischen Survey

Jun 15, 2023 | DevOps

Dieser Artikel konzentriert sich auf Ansible, ein Open-Source-Konfigurationsmanagement-Tool unterstützt von Red Hat, das für Server, Switches und Kubernetes Operators genutzt wird. Er betont Ansible Towers Fähigkeit, komplexe Systeme zu verwalten und seine API zur dynamischen Anpassung zu nutzen.

Autor: Elio Lopez

Ansible Tower Implementierung

Einleitung

Ansible ist ein Konfigurationsmanagement-Tool. Da es eine passwortlose ssh-Verbindung zu den Zielen verwendet, ist kein Agent erforderlich, was ein Vorteil gegenüber anderen Konfigurationsmanagement-Tools ist. Es kann nicht nur für die Verwaltung von Servern, sondern auch von Switches verwendet werden und verfügt auch über ein Framework zum Schreiben von Kubernetes Operators (!).

Es wird von Redhat unterstützt, hat aber eine starke Open-Source-Community, die alle Arten von Playbooks und Rollen schreibt, die „Rezepte“ sind, die einfach installiert und gegen die Ziele verwendet werden können. Ansible eignet sich hervorragend für die Verwendung über die CLI, aber wenn eine komplexe Landschaft zu verwalten ist, kommt Ansible Tower (AWX in seiner Open-Source-Version) zum Einsatz. Mit Ansible Tower können die Administratoren Workflows schreiben, d. h. Gruppen von Playbooks, die eine Survey als Frontend haben können, so dass die Benutzer sich einfach selbst bedienen und auswählen können, welche Art von Ressourcen sie konfigurieren/löschen möchten.

Die Surveys sind derzeit „statisch“, aber da Ansible Tower auch eine API zur Verfügung hat, bedeutet dies, dass wir sie manipulieren können, um sie dynamisch zu ändern, indem wir das Community-uri-Modul und den Ansible Tower selbst als Ziel verwenden. 

Das Hauptziel ist es, die Auswahlliste in einer Umfrage dynamisch zu aktualisieren. Die Informationen zu den Listenelementen stammen dabei aus einer anderen Quelle oder demselben Tower-Host.

In unserem Beispiel verwenden wir einen Workflow, um einen Dienst zu entfernen, dessen Liste dann automatisch aktualisiert wird.

Ansible Tower dynamischen survey playbook

Du kannst den Subtask in meinem Github Repo verwenden, indem du die Ziel-Workflow-ID und die aktualisierte Liste übergibst und den match_key und match_value festlegst, die ersetzt werden sollen.

So sieht der Survey des Workflows in der GUI aus:

Ansible Tower 1

Und so sieht die Survey in der API-Perspektive aus:

Ansible Tower 2 (Elio)

Unser Ziel ist es, den Wert „choices“ im ersten Element der „spec„-Liste (die eigentlich ein Dictionary ist) zu aktualisieren, ohne die anderen Elemente in der Survey zu verändern.

Nehmen wir an, die Service-Liste existiert bereits an anderer Stelle (z. B. in einer Firewall) und es kommt ein neuer Dienst hinzu, der in der Survey aktualisiert werden muss.

Für unser Beispiel habe ich die neue Liste der Einfachheit halber manuell erstellt, aber diese sollte von einer anderen API kommen.

- name: services_list build
  set_fact:
    services_list: “service1\nservice2\nservice3\nservice4\nservice5\n"

- name: services_list debug
  debug: 
    msg: "{{ services_list }}"

Sobald ich die neue Auswahlliste habe, brauche ich die target_template_id, die in der API URL zu sehen ist.

Dann können wir die Subtasks wie folgt verwenden:

- name: Update surveys for workflow job templates
  include: survey_update.yml template_id={{ target_template }} new_services_list={{ new_services_list }} 

Anschließend springen wir zur Teilaufgabe survey_update.yml, in der die aktuelle Survey abgerufen wird:

- name: "Get current survey from {{ template_id }} survey"
  uri:
    url: "{{ tower_endpoint }}workflow_job_templates/{{ template_id }}/survey_spec/"
    method: GET
    user: "{{ tower_user }}"
    password: "{{ tower_pass }}"
    validate_certs: False
    force_basic_auth: yes
    status_code: 200
    body_format: json  
  register: current_survey

Im nächsten Schritt erstellen wir zwei Listen. Eine mit der Zielspezifikation (target_spec_list), die wir ändern wollen, und eine weitere Liste mit allen anderen Elementen (trimmed_spec_list), die wir später hier verwenden:

- name: "Remove the list element which contains {{ match_value }} variable"
  set_fact: 
       trimmed_spec_list: "{{ current_survey.json.spec|rejectattr( match_key , 'match', match_value)|list }}"

- name: "Select target survey which contains {{ match_value }} variable"
  set_fact: 
       target_spec_list: "{{ current_survey.json.spec|selectattr( match_key , 'match', match_value)|list }}"

Um festzulegen, welche Umfrage ausgewählt werden soll, verwende ich zwei generische Variablen, die in vars/main.yml enthalten sind:

tower_endpoint: "https://tower.organization.org/api/v2/"
target_template: 89
match_key: "variable" 
match_value: "service" # the value to match in the survey list element

Das bedeutet, dass der Key als “variable” fungiert und der Wert in unserem Fall als “service”. Der Einfachheit halber habe ich hier als Key “variable” rausgesucht, ohne dass es ein zwangsläufiges Erfordernis ist.

Ansible Tower 3 (Elio)

Jetzt extrahieren wir das erste Dict-Element und ersetzen den Wert „choices„, der als Variable an die Unteraufgabe übergeben wurde:

- name: "extract the survey dict that matches {{ match_value }} variable"
  set_fact: 
      new_survey_dict: "{{ target_spec_list[0] }}"

- name: replace the choices element in the dict
  set_fact: 
    new_survey_dict: "{{ new_survey_dict | combine(new_item, recursive=true) }}"
  vars:
    new_item: { 'choices': "{{ new_services_list }}" }
 with_dict: "{{ new_survey_dict }}"

Jetzt können wir die aktualisierte_spec_list nutzen. Diese fügst du einfach zur trimmed_spec_list hinzu, die wir am Anfang genommen haben, um die final_spec_list zu erstellen:

- name: Create the new services list element with updated choices
  set_fact: 
    updated_spec_list: "{{ updated_spec_list | default([]) + [ new_survey_dict] }}"

- name: Generate the new spec list
  set_fact: 
    final_spec_list: "{{ updated_spec_list + trimmed_spec_list }}"

Zum Schluss erstellen wir den erforderlichen json-Payload mit der aktualisierten Survey und stellen ihn zurück in den Tower:

- name: Create and add items to new_survey dictionary
  set_fact: 
      new_survey: "{{ new_survey | default({}) | combine ({ item.key : item.value }) }}"
  with_items:
    - { 'key': 'description' , 'value': ''}
    - { 'key': 'name' , 'value': ''}
    - { 'key': 'spec' , 'value': "{{ final_spec_list }}" }

- name: "put the survey back on {{ template_id }} survey playbook"
  uri:
    url: "{{ tower_endpoint }}workflow_job_templates/{{ template_id }}/survey_spec/"
    method: POST
    user: "{{ tower_user }}"
    password: "{{ tower_pass }}"
    validate_certs: False
    force_basic_auth: yes
    status_code: 200
    body:
      "{{ new_survey }}"  
    body_format: json

Nachdem das Ansible Playbook gelaufen ist, aktualisieren wir die Survey mit der neuen Dienstliste:

4

Fazit

Mit Ansible Tower können wir die Bereitstellung und Änderungen an unserer Infrastruktur automatisieren. Surveys sind hilfreich für die Interaktion mit dem Benutzer, aber wenn die Optionen statisch definiert sind, sind wir gezwungen, sie manuell zu aktualisieren. Wir können unsere Infrastruktur täglich abfragen (durch einen Job in Ansible Tower), um die für die Benutzer verfügbaren Optionen (z. B. DNS-Zonen) auf dem neuesten Stand zu halten, was die Workflows robuster und weniger fehleranfällig macht.

Auf diese Weise können wir nicht nur die Bereitstellung unserer Infrastruktur automatisieren, sondern auch die Informationen auf dem neuesten Stand halten, wenn sie von anderen Quellen außerhalb des Towers abhängen.

Sie suchen einen Partner für Ihr Projekt?

Wir geben unser Bestes, um Sie zufrieden zu stellen.

Auf der Suche nach einem spannendem Job?

Schau dir jetzt unsere offenen Stellen an und finde deinen neuen Job bei Pexon.