Seite wählen

NETWAYS Blog

Variablen mergen mit Ansible

 

Ansible kann Variable standardmäßig nicht mergen (miteinander vereinen, ineinander übergeben), sondern nur an verschiedenen Stellen überschreiben. Dies ist  bei manchen Anwendungsfällen unpraktisch, unübersichtlich und fehleranfällig wie z. B. beim ausrollen von SSH-Keys, Usern oder Firewall-Regeln. Angenommen wir wollen sowohl allgemeine SSH-Keys auf alle Server ausrollen, als auch extra Schlüssel zu bestimmten Servern zuordnen. In diesem Fall können wir unter group_vars/all  die allgemeinen Keys in einem Array oder in einem Dictonary definieren und unter group_vars/group_name oder host_vars/hostname die vorherigen Keys plus die Extras eintragen. Eine andere Möglichkeit wäre, dass wir die SSH-Keys (allgemeine und spezifische) in unterschiedlichen Variablen packen, die jeweils mit einem Task behandelt werden können. Die oben erwähnte Möglichkeiten machen besonders bei großen Umgebungen kein Spaß und ergibt am Ende entweder unübersichtliche Variablen-Definition oder statische Rollen.

In diesem Zuge wäre hiera im Kombination mit dem hiera lookup plugin eine gute Lösung. hiera ist ein hierarchisch durchsuchbarer key => value Store. In diesem Blogpost werde ich anhand eines Beispiels demonstrieren, wie hiera mit Ansible eingesetzt werden kann. Dieses Beispiel befasst die Verteilung der Konfigurationen für Gruppen, Benutzers und SSH-Keys auf zwei Server.  Bei allen Linux-Distrubtionen gibt es in unserem Fall keine Unterschiede. Alle Schritte erfolgen auf dem Ansible Controller.  Ich fange mal mit der hiera Installation an.

# yum install ruby -y
# gem install hiera

Unter /etc/hiera.yaml liegt die hiera-Konfiguration.

:backends:
- yaml
:hierarchy:
- "%{groups}"
- "%{hosts}"
- common

:yaml:
:datadir: /etc/hieradata

:merge_behavior: deeper

Unter hierarchy definieren wir die Stufen aufsteigend/absteigend, bei denen hiera nach einem Schlüssel suchen soll. hiera fängt mit groups an zu suchen und endet mit common. common trifft immer zu und gilt in unserem Fall für alle Server. groups und hosts sind Facts, die wir später dem Ansible playbook übergeben wollen. Der Pfad zu suchenden Daten bzw. Schlüsseln kann man beliebig ändern. Außerdem kann man bei :merge_behavior: eine der drei folgenden Optionen einstellen: native, deep, deeper. Um die Unterschiede zu erfahren, könnt ihr das hier nachlesen.

In der Ansible-Inentory stehen zwei Hosts jweils unter einer Gruppe.

[webserver]
web1.shared
web2.shared
web3.shared

[monitoring]
icinga-master1.shared

Unter /etc/hieradata/common.yaml liegen die SSH-Keys, die auf alle Server ausgerollt werden müssen, da common.yaml als unser Default für alle Hosts gilt, wie schon vorher erwähnt wurde.

---
ssh_users:
  - name: 'sergio'
    comment: 'sergio@example.com'
    key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDjuyGPTdo17ATAu69v2Bqui/f38e1uqOLvObiMw+uS9+Raxy5sO12pagVJeN9BTQaL09Sp9Dw+ozozg67WXfgTo+yoC5wy5a3d3Ihl4XJ/68SFUmEO2qo8Zg3914teL+FQMw5BE52LyqJjjBulGQ+jloGaldqxBfvjrmGMnz3mafCLtix+/UO1W+51gkea925XAOQ+KR1u1WFbEM3E6TfAoMv5Ev41e3jIcS+O+dnBqiZLsSIF3h72ni4eGr6h6x51itoFGQhN1jRcK9J5QfJG4O8OciReUCU5gETLi8RgFuBlQqDztZT1jGPbpkH2/swt3WGBUGOv+GizQg8iK9F"
    authorize_to: 'root'
    state: present

  - name: 'david'
    key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDRsAZ3DKxisCchDBd1dqtM9kPEgq+8MXbkClYVAoAlidx6qLz8Z6zBeSZ8ob+ae0dEegoN31mXv9ITaFhIdgIUxP0s54Mb4kgc9FE4njNRlb7xkTwsU3C6G7JUN9pJ64ucEqLI2iJ1JLI+zh0u5sWZS0tMoyEy73ZaAE6O32XyywIw5X+Uw7ISwqeeFsnWc4faKoWVgjt/s1MsuEOGsD1ocUxVPG7PKMEy8LQtQ7WL+RybV/TYH56hxBMi5H4BfC61Wm6Fn7pck5pCMzZOwstYikHoTWhJ16UYoJ6MubddoAOq/JyTimC/559U3lYgdHBXGJyCyW2xcGF7blmh0U97"
    authorize_to: 'root'
    state: absent

Unter /etc/hieradata/monitoring.yaml steht extra Konfiguration für die Hosts, die der monitoring-Gruppe zugeordnet sind.

user_groups:
  - name: 'nagios'
    state: 'present'

users:
  - name: 'icinga'
    shell: '/bin/bash'
    groups: 'nagios'
    append: yes
    state: 'present'

ssh_users:
  - name: 'alex'
    comment: 'sergio@example.com'
    key: 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDCu5vAfoePg8Z5Tc3uOfua+RvxpA/WyDNKtHJze/pogssAtA+RZ6wdmvwuBGVFILgVKrpHItsUWZwWwsrNF0rjXV4MsPZzS8TbUNISoV7sETOk6pM1vg8ldy5XEszCokFsHmYLfovlqaICneKwiZ4SfQo21WjgzNXeVSND/1W5BZNAptobH6HC9oASRgeidwbDjDEux8//zvjjcIQlj9HXGmsKT5/r2+LR5Wo8rRkhdC+sbDJcDfN9OFg2Wo+PmwX6ArMfZ3oqh4xEGS3hN4Yo8lAVK8APPKNojtKv53qnFNTkfNrHRw9MbiXpPiYMFmKtGZztc9vPNKB6kBF1DFL/'
    authorize_to: 'icinga'
    state: present

Die Konfigurationen unter /etc/hieradata/web1.shared.yaml werden nur dem web1.shared angeordnet.

---
user_groups:
  - name: 'web-group'
    state: 'present'

  - name: 'admins'
    state: 'present'

users:
  - name: 'web-user'
    shell: '/bin/bash'
    groups: 'web-group, admins'
    append: yes
    state: 'present'

ssh_users:
  - name: 'mueller'
    comment: 'web-user@example.com'
    key: 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCg6fvX0UIN22fPHHbSxPZQCyeqa8j2AEeqF7TlX3TSkJ17Q7Rz3g4B1RG8L+WfI+eb11bmESPTQ5Pym27qmNvfYl6dJynSdrRihnNj4Id1fKEzoW6J835rtRmaKD0V7KJ1JJvip0m24oIlFJIYSfShWSrOuvUgP3TpYUsU3KA2AQhoNtXWhgUM+wwFfCF3qZ4AX5zhQFy+bdqyYudmW99DasuZjaCq3djoMh9Ocm9lRPdDTpGS/Yb1yAqKU7rizrwlS3EmNcbQddRd2ZXFQnustfSX+ejo7PcEpimAPpcC2jbbS38pFbYdIvdm7BXsRMpsOXEuEZLrrbZMsPpEQ8FJ'
    authorize_to: 'web-user'
    state: present

Unser playbook kann so aussehen.

---
- hosts: all
  remote_user: root
  become: true
  tasks:
    - name: Set facts
      set_fact:
        ssh_users: "{{ lookup('hiera', 'ssh_users --array hosts={{ inventory_hostname }}  groups={{ item }} --format yaml')|from_yaml }}"
        user_groups: "{{ lookup('hiera', 'user_groups --array hosts={{ inventory_hostname }}  groups={{ item }} --format yaml')|from_yaml }}"
        users: "{{ lookup('hiera', 'users --array hosts={{ inventory_hostname }}  groups={{ item }} --format yaml')|from_yaml }}"
      loop: "{{ group_names }}"
 
    - name: Create groups
      group:
        name: "{{ item.name }}"
        state: "{{ item.state }}"
      loop: "{{ user_groups | default ([]) }}"
  - name: Create users
      user:
        name: "{{ item.name }}"
        shell: "{{ item.shell | default (omit) }}"
        state: "{{ item.state }}"
        append: "{{ item.append }}"
      loop: "{{ users | default ([]) }}"

    - name: Set ssh-keys
      authorized_key:
        user: "{{ item.authorize_to }}"
        state: "{{ item.state }}"
        key: "{{ item.key }}"
      loop: "{{ ssh_users | default ([]) }}"

Das lookup-Plugin nutzt hiera um auf Daten bzw. Schlüssel zugreifen zu können. Wir geben die zu suchenden Schlüssel mit, z. B. ssh-users. Wir übermitteln auch die Facts die hiera erwartet, nämlich hosts und groups. Man kann anstatt “inventory_hostname” “ansible_hostname” oder “ansible_fqdn” verwenden. Allerdings muss man die Datein unter /etc/hieradata entsprechend benennen. Groupe-Fact geben wir durch einen Loop über den Ansible-Fact group_names an die hiera weiter, in dem alle Gruppen der Inventory aufgelistet sind. Die Rückgabe ist in unserem Fall ein array, man kann auch einen hash auswählen. Die standardmäßige Format bei hiera is ruby, allerdings stellen wir das auf yaml um, damit Ansible die Format verarbeiten kann.

# ansible-playbook hiera-playbook.yml -i inventory

PLAY [all] ****************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************************************************************************************************************************************
ok: [web1.shared]
ok: [icinga-master1.shared]

TASK [Set facts] **********************************************************************************************************************************************************************************************************************
ok: [icinga-master1.shared] => (item=monitoring)
ok: [web1.shared] => (item=webserver)

TASK [Create groups] ******************************************************************************************************************************************************************************************************************
ok: [icinga-master1.shared] => (item={u'state': u'present', u'name': u'nagios'})
ok: [web1.shared] => (item={u'state': u'present', u'name': u'web-group'})
ok: [web1.shared] => (item={u'state': u'present', u'name': u'admins'})

TASK [Create users] *******************************************************************************************************************************************************************************************************************
ok: [web1.shared] => (item={u'groups': u'web-group, admins', u'state': u'present', u'shell': u'/bin/bash', u'name': u'web-user', u'append': True})
ok: [icinga-master1.shared] => (item={u'groups': u'nagios', u'state': u'present', u'shell': u'/bin/bash', u'name': u'icinga', u'append': True})

TASK [Set ssh-keys] *******************************************************************************************************************************************************************************************************************
ok: [icinga-master1.shared] => (item={u'comment': u'sergio@example.com', u'state': u'present', u'authorize_to': u'icinga', u'name': u'alex', u'key': u'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDCu5vAfoePg8Z5Tc3uOfua+RvxpA/WyDNKtHJze/pogssAtA+RZ6wdmvwuBGVFILgVKrpHItsUWZwWwsrNF0rjXV4MsPZzS8TbUNISoV7sETOk6pM1vg8ldy5XEszCokFsHmYLfovlqaICneKwiZ4SfQo21WjgzNXeVSND/1W5BZNAptobH6HC9oASRgeidwbDjDEux8//zvjjcIQlj9HXGmsKT5/r2+LR5Wo8rRkhdC+sbDJcDfN9OFg2Wo+PmwX6ArMfZ3oqh4xEGS3hN4Yo8lAVK8APPKNojtKv53qnFNTkfNrHRw9MbiXpPiYMFmKtGZztc9vPNKB6kBF1DFL/'})
ok: [web1.shared] => (item={u'comment': u'web-user@example.com', u'state': u'present', u'authorize_to': u'web-user', u'name': u'mueller', u'key': u'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCg6fvX0UIN22fPHHbSxPZQCyeqa8j2AEeqF7TlX3TSkJ17Q7Rz3g4B1RG8L+WfI+eb11bmESPTQ5Pym27qmNvfYl6dJynSdrRihnNj4Id1fKEzoW6J835rtRmaKD0V7KJ1JJvip0m24oIlFJIYSfShWSrOuvUgP3TpYUsU3KA2AQhoNtXWhgUM+wwFfCF3qZ4AX5zhQFy+bdqyYudmW99DasuZjaCq3djoMh9Ocm9lRPdDTpGS/Yb1yAqKU7rizrwlS3EmNcbQddRd2ZXFQnustfSX+ejo7PcEpimAPpcC2jbbS38pFbYdIvdm7BXsRMpsOXEuEZLrrbZMsPpEQ8FJ'})
ok: [web1.shared] => (item={u'comment': u'sergio@example.com', u'state': u'present', u'authorize_to': u'root', u'name': u'sergio', u'key': u'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDjuyGPTdo17ATAu69v2Bqui/f38e1uqOLvObiMw+uS9+Raxy5sO12pagVJeN9BTQaL09Sp9Dw+ozozg67WXfgTo+yoC5wy5a3d3Ihl4XJ/68SFUmEO2qo8Zg3914teL+FQMw5BE52LyqJjjBulGQ+jloGaldqxBfvjrmGMnz3mafCLtix+/UO1W+51gkea925XAOQ+KR1u1WFbEM3E6TfAoMv5Ev41e3jIcS+O+dnBqiZLsSIF3h72ni4eGr6h6x51itoFGQhN1jRcK9J5QfJG4O8OciReUCU5gETLi8RgFuBlQqDztZT1jGPbpkH2/swt3WGBUGOv+GizQg8iK9F'})
ok: [icinga-master1.shared] => (item={u'comment': u'sergio@example.com', u'state': u'present', u'authorize_to': u'root', u'name': u'sergio', u'key': u'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDjuyGPTdo17ATAu69v2Bqui/f38e1uqOLvObiMw+uS9+Raxy5sO12pagVJeN9BTQaL09Sp9Dw+ozozg67WXfgTo+yoC5wy5a3d3Ihl4XJ/68SFUmEO2qo8Zg3914teL+FQMw5BE52LyqJjjBulGQ+jloGaldqxBfvjrmGMnz3mafCLtix+/UO1W+51gkea925XAOQ+KR1u1WFbEM3E6TfAoMv5Ev41e3jIcS+O+dnBqiZLsSIF3h72ni4eGr6h6x51itoFGQhN1jRcK9J5QfJG4O8OciReUCU5gETLi8RgFuBlQqDztZT1jGPbpkH2/swt3WGBUGOv+GizQg8iK9F'})
ok: [icinga-master1.shared] => (item={u'state': u'absent', u'authorize_to': u'root', u'name': u'david', u'key': u'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDRsAZ3DKxisCchDBd1dqtM9kPEgq+8MXbkClYVAoAlidx6qLz8Z6zBeSZ8ob+ae0dEegoN31mXv9ITaFhIdgIUxP0s54Mb4kgc9FE4njNRlb7xkTwsU3C6G7JUN9pJ64ucEqLI2iJ1JLI+zh0u5sWZS0tMoyEy73ZaAE6O32XyywIw5X+Uw7ISwqeeFsnWc4faKoWVgjt/s1MsuEOGsD1ocUxVPG7PKMEy8LQtQ7WL+RybV/TYH56hxBMi5H4BfC61Wm6Fn7pck5pCMzZOwstYikHoTWhJ16UYoJ6MubddoAOq/JyTimC/559U3lYgdHBXGJyCyW2xcGF7blmh0U97'})
ok: [web1.shared] => (item={u'state': u'absent', u'authorize_to': u'root', u'name': u'david', u'key': u'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDRsAZ3DKxisCchDBd1dqtM9kPEgq+8MXbkClYVAoAlidx6qLz8Z6zBeSZ8ob+ae0dEegoN31mXv9ITaFhIdgIUxP0s54Mb4kgc9FE4njNRlb7xkTwsU3C6G7JUN9pJ64ucEqLI2iJ1JLI+zh0u5sWZS0tMoyEy73ZaAE6O32XyywIw5X+Uw7ISwqeeFsnWc4faKoWVgjt/s1MsuEOGsD1ocUxVPG7PKMEy8LQtQ7WL+RybV/TYH56hxBMi5H4BfC61Wm6Fn7pck5pCMzZOwstYikHoTWhJ16UYoJ6MubddoAOq/JyTimC/559U3lYgdHBXGJyCyW2xcGF7blmh0U97'})

PLAY RECAP ****************************************************************************************************************************************************************************************************************************
icinga-master1.shared      : ok=5    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
web1.shared                : ok=5    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

 

Wenn Du mehr über Ansible lernen und Dein wissen vertiefen willst, wäre eine Teilnahme an einer Ansible Schulung nicht verkehrt.

 

Afeef Ghannam
Afeef Ghannam
Support Engineer

Afeef hat seine Ausbildung Als Fachinformatiker in Richtung Systemintegration im Juli 2020 bei NETWAYS absolviert, seitdem unterstützt er die Kollegen im Support und bei der Betriebsunterstützung. Nach der Arbeit macht er gerne Sport, trifft Freunde oder mag es Filme zu schauen.

Foreman’s 12 birthday – we will have a virtual party

Beginning with Foreman’s 7th birthday in the year 2016 we are organizing an annual party to celebrate with the awesome community. As we partnered up with ATIX for organizing this event, it was their turn last year and with Covid19 they had the additional challenge to move a social event from meeting in person to online. While they did great, I had high hopes I could return back to normal in this year, but unfortunately also this year we have to stay virtual.

Nevertheless I can announce we will have another Foreman Birthday event on July 1st, 15:00 (CEST). We plan to have 5 to 6 30 minute talks with moderation by me accompanied and some kind of chat for live discussion and Q&A followed by a social event.

As we are still in the planing phase I can not go into detail about the social event or the chat solution but I can already confirm the first two talks.

  • Lukáš Zapletal will tell us “The story of webhooks plugin” as a mixture of technical talk and community success story.
  • Dana Singleterry will give as a “Red Hat Product manager update” so we will hear what Red Hat is planing for the next releases.

If you like to give a talk please get in touch with via email. We aim for a wide variety of talks, be it a new plugin or some new tricks for an old one, a case study showing your environment, about Foreman itself, Katello/Satellite/Orcharhino, Pulp, Candlepin or even Puppet and Ansible or the Community. Everything related to Foreman will be considered. We plan to have all talks pre-recorded and will provide guidance for doing so. After the talk we want to give everyone the chance to ask questions, so the speaker can answer them live.

So save the date and watch this thread in the Foreman Community for always up-to-date information. I hope to meet you all at the event! My plan is you will miss nothing of our normal program except the cake from this virtual event! 😉

Foreman Birthday Cake

Graphics used “Happy Birthday” by Hendrike under CC BY-SA 3.0 and “Foreman Logo” by Red Hat Inc. under CC BY-SA 3.0
Dirk Götz
Dirk Götz
Principal Consultant

Dirk ist Red Hat Spezialist und arbeitet bei NETWAYS im Bereich Consulting für Icinga, Puppet, Ansible, Foreman und andere Systems-Management-Lösungen. Früher war er bei einem Träger der gesetzlichen Rentenversicherung als Senior Administrator beschäftigt und auch für die Ausbildung der Azubis verantwortlich wie nun bei NETWAYS.

Ansible – AWX|Tower State handling on Workflows

The Ansible Tower or its upstream AWX provides an easy to use GUI to handle Ansible tasks and schedules. Playbooks are configured as templates and as the name suggests, they can be modified to the needs, extended by variables, a survey or tags.

Furthermore those templates can be logically grouped, connected and visualised in Workflows.

The downside to those Workflows, all playbooks affected by this are executed separately and can’t access each others variables. On first glance we maybe only spot that we can define variables for the whole workflow but those are not changeable throughout the flow.

But there is a solution, which is the module set_stats. This module allows to save or accumulate variables and make them available for other playbooks within the workflow.

As an example we could use the monitoring environment when setting downtimes.

workflow

As a downtime is created before a maintenance and should be gone when the maintenance is done. This creates a dependency on the first task, which can be solved as we save the result of the first tasks with the set_stats module.


      - name: schedule downtimes
        icinga2_downtimes:
          state: "{{ downtime_icinga_state | default('present') }}"
          host: ***
          author: "{{ icinga2_downtimes_author | default('ansible_downtime') }}"
          comment: "{{ icinga2_downtimes_comment | default('Downtime scheduled by Ansible') }}"
          duration: "{{ icinga2_downtimes_duration | default(omit) }}"
        register: content
 
      - set_stats:
          data:
            downtime: "{{ content }}"

The content of the data will be now available to all playbooks included by the workflow. The variable is also shown as artefacts in the GUI.

artefacts

Keep in mind that the variable will be part of the extra variables for all other playbooks. As covered in the variable precedence it will overwrite any other variable named the same.

With this module you can reorganise your playbooks and connect them in workflows. This allows you to have a more flexible automation than before.

Check out our Blog for more awesome posts and if you need help with Ansible send us a message or sign up for one of our trainings!

Thilo Wening
Thilo Wening
Consultant

Thilo hat bei NETWAYS mit der Ausbildung zum Fachinformatiker, Schwerpunkt Systemadministration begonnen und unterstützt nun nach erfolgreich bestandener Prüfung tatkräftig die Kollegen im Consulting. In seiner Freizeit ist er athletisch in der Senkrechten unterwegs und stählt seine Muskeln beim Bouldern. Als richtiger Profi macht er das natürlich am liebsten in der Natur und geht nur noch in Ausnahmefällen in die Kletterhalle.

Adblocker und Pi-Hole

Pi-Hole ist ein netzwerkweiter Adblocker, aber was ist eigentlich Adblocker? Ein Werbeblocker bzw. Adblocker ist ein Programm, mit dem verschiedene Arten von Werbung aus der Webanfragen eines Webbenutzers entfernt werden. Diese Programme zielen auf bestimmte Arten von Anzeigen ab, wie z. B. Popups, Bannerwerbung und andere gängige Formen der Online-Werbung, sodass ein Benutzer ohne störende Ablenkungen oder Unterbrechungen im Internet surfen kann. Die Adblock-Technologie basiert auf einfachen Listen, sogenannten Filterlisten, die festlegen was blockiert und ausgeblendet werden soll oder was auf den von Ihnen besuchten Seiten angezeigt werden soll. Diese Listen bestehen einfach aus einer Liste von URLs in Form einer “Zulassungsliste” oder einer “Sperrliste”.

Wenn Sie eine Website besuchen, überprüft der Adblocker schnell, ob diese Website in einer dieser Filterlisten enthalten ist. Wenn dies der Fall ist, wird die Anforderung an externe Inhalte blockiert und die Anzeige wird nicht auf die Webseite heruntergeladen. Kurz gesagt, die Adblock-Technologie besteht aus einer Reihe von Regeln, die in diesen Filterlisten festgelegt sind und festlegen, was auf den von Ihnen besuchten Webseiten blockiert oder nicht blockiert werden soll. Es gibt die Möglichkeit den Adblocker entweder auf Browser installieren oder im Netzwerk konfiguriere.

Pi-Hole ist eine kostenlose Open-Source-Software zum Einrichten eines DNS- (Domain Name Service) und DHCP-Servers (Dynamic Host Configuration Protocol) mit integrierten Funktionen, mit denen Anzeigen, Tracker und andere Websites blockiert werden können. Anstatt Adblocker auf jedem Gerät und jedem Browser zu installieren, können wir Pi-Hole einmal in unserem Netzwerk als DNS-Server installieren und alle unsere Geräte schützen. Da Pi-Hole anders funktioniert als ein browserbasierter Werbeblocker, blockiert Pi-Hole Anzeigen auch an nicht traditionellen Orten, z. B. in Spielen und auf Smart-TVs. Pi-Hole braucht nicht so viel Rechenpower, daher funktioniert er problemlos auf alle Raspberry-Pi Modellen mit ein laufendem Linux-Betriebssystem wie Ubuntu oder Raspbian. Pi-hole funktioniert auf DNS-Ebene (Domain Name Service). DNS wird von Ihrem Computer verwendet, um einen in einen Webbrowser eingegebenen Domainnamen (z. B. build5nines.com) in die IP-Adresse (z.B. 8.8.8.8) umzuwandeln, mit der der Computer eine Verbindung herstellt, um den angeforderten Namen herunterzuladen und anzuzeigen. Diese DNS-Suche wird nicht nur im Webbrowser durchgeführt, sondern von jeder Software, die die Kommunikation mit einem Server im Internet anfordert. z.B. Apps auf Ihrem Smartphone, Computer, Tablet oder anderen Geräten. Durch das Einrichten von Pi-Hole als DNS-Server in Ihrem Netzwerk werden alle DNS-Namensauflösungsanforderungen abgefangen und Sie können diejenigen blockieren, die Sie nicht möchten. wie Anzeigen, Tracker oder sogar NSFW-Websites. Als DNS-Server ist es so eingerichtet, dass unerwünschter / unerwünschter Datenverkehr in Ihrem gesamten Netzwerk blockiert wird, ohne dass etwas auf Ihrem Smartphone, Laptop oder anderen Geräten installiert werden muss. Sie richten einfach das Pi-Hole ein, konfigurieren Ihr Netzwerk und alles funktioniert für alle mit dem Netzwerk verbundenen Geräte.

Am häufigsten wird von Pi-Hole gesprochen, um Website-Werbung in einem Heimnetzwerk zu blockieren. Dies ist nur ein sehr spezifischer Anwendungsfall. Pi-Hole kann in jedem Netzwerk verwendet werden, sofern die Hardware, auf der es installiert ist, über die Ressourcen verfügt, um alle DNS-Abfragen dieses Netzwerks zu verarbeiten. Daher können Sie Pi-hole auch in einem Netzwerk für kleine Unternehmen installieren, um unerwünschte Websites zu blockieren. Dies ist eine wirklich günstige Option für Unternehmen.

Saeid Hassan-Abadi
Saeid Hassan-Abadi
Junior Consultant

Saeid hat im September 2019 seine Ausbildung zum Fachinformatiker im Bereich Systemintegration gestartet. Der gebürtige Perser hat in seinem Heimatland Iran Wirtschaftsindustrie-Ingenieurwesen studiert. Er arbeitet leidenschaftlich gerne am Computer und eignet sich gerne neues Wissen an. Seine Hobbys sind Musik hören, Sport treiben und mit seinen Freunden Zeit verbringen.

Ansible – Loop over multiple tasks

ansible logo

The last time I wrote about Ansible and the possibility to use blocks to group multiple tasks. Which you can read here. Sadly this feature does not work with loop, so there is no clean way to loop over multiple tasks in a play without writing the same loop statement at tasks over and over.

But when we come across the need of tasks which depend on each other, for example, we execute a script with a certain parameter and its result is necessary for the upcoming tasks.

Let’s go through a common example, creating a site consists of a few steps. Creating the directory, creating the vhost and then enabling the site.


- name: "create {{ site }} directory"
  file:
    ensure: directory
    dest: "/var/www/{{ site }}"
    
- name: "create {{ site }}"
  template:
    src: vhost.j2
    dest: "/etc/apache2/sites-available/{{ site }}"
  register: vhost

- name: "enable {{ site }}"
  command: /usr/sbin/a2ensite "{{ site }}"
  register: result
  when: vhost.changed
  changed_when: "'Enabling site' in result.stdout"
  notify: apache_reload

We could use a loop for each tasks and afterwards find the right result for the next task to depend on. But the styleguide will warn you if you try to use Jinja2 syntax in when statements.

So the best solution to this is to use include_tasks, which can include a file with tasks. This task is allowed to have a loop directive and so we can include it multiple times.
Lets see how this would apply to our scenario:


- set_fact:
    sites:
      - default
      - icingaweb2

- name: create vhosts
  include_tasks: create-vhosts.yml
  loop: "{{ sites }}"
  loop_control:
    loop_var: site


In the Result we can see clearly that all tasks are applied for each element in the sites variable.


TASK [set_fact] *********************************************
ok: [localhost]

TASK [create vhosts] ****************************************
included: /Users/twening/Documents/netways/ansible_test20/create-vhosts.yml for localhost => (item=default)
included: /Users/twening/Documents/netways/ansible_test20/create-vhosts.yml for localhost => (item=icingaweb2)

TASK [create default directory] *****************************
ok: [localhost]

TASK [create default] ***************************************
ok: [localhost]

TASK [enable default] ***************************************
ok: [localhost]

TASK [create icingaweb2 directory] **************************
ok: [localhost]

TASK [create icingaweb2] ************************************
ok: [localhost]

TASK [enable icingaweb2] ************************************
ok: [localhost]

PLAY RECAP **************************************************
localhost                  : ok=10   changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0


Check out our Blog for more awesome posts and if you need help with Ansible send us a message or sign up for one of our trainings!

Thilo Wening
Thilo Wening
Consultant

Thilo hat bei NETWAYS mit der Ausbildung zum Fachinformatiker, Schwerpunkt Systemadministration begonnen und unterstützt nun nach erfolgreich bestandener Prüfung tatkräftig die Kollegen im Consulting. In seiner Freizeit ist er athletisch in der Senkrechten unterwegs und stählt seine Muskeln beim Bouldern. Als richtiger Profi macht er das natürlich am liebsten in der Natur und geht nur noch in Ausnahmefällen in die Kletterhalle.

Veranstaltungen

Di 18

Icinga 2 Fundamentals Training | Online

Mai 18 @ 09:00 - Mai 21 @ 17:00
Jun 15

stackconf online

Juni 15 - Juni 17
Jun 22

Ansible Fundamentals Training | Online

Juni 22 @ 09:00 - Juni 24 @ 17:00
Jun 22

Kubernetes Quick Start | Online

Juni 22 @ 09:00 - 17:00
Jun 25

Ansible AWX (Tower) Training | Online

Juni 25 @ 09:00 - 17:00