StartseitePortfolioBlog

Mac einrichten leicht gemacht - mit Ansible

By Lukas Mösle
Published in Miragon
October 11, 2022
6 min read
Mac einrichten leicht gemacht - mit Ansible

Jeder von uns hat seinen ganz eigenen Ablauf seinen PC einzurichten. Für gewöhnlich dauert es immer ein paar Tage bis man alle Programme installiert und konfiguriert, alle Git Repositories gecloned und die Entwicklungsumgebung eingerichtet hat. Nachdem das immer sehr Zeit aufwendig und um ehrlich zu sein auch ein bisschen nervig ist, habe ich damit begonnen mein PC Setup in Infrastructure as Code (IaC) Manier zu beschreiben, um schließlich meinen PC automatisiert einrichten zu können. IaC Tools gibt es wie Sand am Meer ich hab mich hierbei für Ansible entschieden, da es Open Source Software ist und ich mit Ansible bereits zuvor gearbeitet habe.

Nachdem ich meinen privaten Linux PC bereits mit einem Ansible Setup automatisiert aufsetze und verwalte, habe ich auch ein solches Setup für mein Arbeits-Macbook bei Miragon erstellt. Die Basis dieses Setups verwenden wir bei Miragon mittlerweile sogar, um Macbooks für neue Kollegen einzurichten und die bereits vorhandenen Macbooks auf einem aktuellen Stand zu halten.

In diesem Blogpost zeige ich, wie wir Ansible einsetzen, um Software auf unseren Macs mit Homebrew zu installieren, die Konfiguration von Entwicklungstools vorzunehmen und Git Repositories zu clonen und zu aktualisieren.

Was ist Ansible

Ansible ist ein Open-Source-Automatisierungswerkzeug zur Orchestrierung und allgemeinen Konfiguration und Administration von Computern

Quelle: https://de.wikipedia.org/wiki/Ansible

Mit Ansible beschreibt man den Zielzustand eines Systems in sogenannten Playbooks (.yml Dateien). Zusätzlich definiert man in einem sogenannten Inventory File die Zielsysteme auf denen das Playbook ausgeführt wird. Wenn man anschließend das Playbook ausführt baut Ansible eine SSH Verbindung zu den Zielsystemen auf und führt die einzelnen Tasks des Playbooks aus. Ansible ist agentless und dementsprechend muss Ansible nur auf dem Host System und nicht auf den Zielsystemen installiert werden.

Ansible Überblick
Ansible Überblick

Infrastructure as Code ist heute zum Standard für die Serveradministration geworden. In diesem Kontext gehört Ansible auch am zu den Bekanntesten und Verbreitesten IaC Tools. Um Ansible (oder ein anderes IaC Tool) führt kein Weg herum bei der Administration von Server. In diesem Kontext trifft man auch besonders häufig auf diese Tools. Aber nachdem ein Desktop Betriebssystem nichts anderes ist, wie ein Server mit grafischer Oberfläche, kann Ansible auch hier problemlos eingesetzt werden. Insbesondere wenn man Linux aber auch Mac als Betriebssystem verwendet.

Ansible trifft Mac

Vor der Verwendung von Ansible müssen lediglich drei manuelle Einrichtungsschritte ausgeführt werden: Den Paketmanager Homebrew installieren, Ansible installieren und unseren SSH-Key in Github hinterlegen.

Homebrew Homebrew verwenden wir als Paketmanager, um Programme zu installieren (https://brew.sh/index_de)

SSH Key Bevor wir Git Repositories von z.B. Github clonen können muss zuerst ein SSH Key erstellt und in Github hinterlegt werden

Ansible Nachdem wir Homebrew installiert haben muss nur noch Ansible mit brew install ansible installiert werden und wir sind startklar.

Software installieren mit Homebrew

Die einfachste Art Software zu installieren ist mit einem Paketmanager. Unter Mac verwenden wir den Paketmanager Homebrew, den wir zuvor bereits installiert haben. Um ein Programm wie z.B. asciiquarium mit Homebrew zu installieren verwenden wir das Ansible Module homebrew. Folgender Ansible Task entspricht dem Befehl brew install asciiquarium.

- name: Install packages with homebrew
  homebrew:
    name:
      - asciiquarium

Software mit Homebrew Cask installieren

Software mit einer grafischen Oberfläche (GUI) kann in Mac OS über Homebrew Cask installiert werden. Hierfür gibt es leider kein eigenes Ansible Module, jedoch können wir hierfür das Shell Module verwenden und direkt den Befehl brew install --cask firefox ausführen.

Bei Ansible definieren wir hierfür einen eigenen Task, der das Shell Modul verwendet und das Command brew install --cask firefox ausführt. In diesem speziellen Fall müssen wir noch zusätzlich die Shell angeben, in der der Befehl ausgeführt werden soll. In unserem Fall ist das die /bin/zsh Shell.

Ansible führt jeden Befehl in einer eigenen non interactive Shell aus. Dabei werden Shell Hooks nicht ausgeführt und Konfigurationsdateien wie z.B. die .zshrc oder .bashrc nicht berücksichtigt. In unserem konkreten Fall kann es passieren, das das brew Executable nicht zur Verfügung steht in einer solchen Shell. Um das Problem zu beseitigen muss der Befehl in der richtigen Shell ausgeführt werden. In diesem Fall ist das die bin/zsh.

- name: Install homebrew cask packages
  shell:
    cmd: brew install --cask {{ item }}
    executable: /bin/zsh
  with_items:
    - google-chrome
    - firefox

Um mehrere Ansible Befehl hintereinander auszuführen kann das with_items Feature von Ansible verwendet werden. Dieses Feature erlaubt es über einen Task mit einer Liste an Werten zu iterieren. Bei der Installation von Cask Paketen müssen wir auf dieses Feature zurückgreifen, um mehrere Programme zu installieren.

Regelmäßige Updates

Eine weitere Aufgabe von Server-Administrator ist es, die auf den Servern installierte Software aktuell zu halten. Bei PCs sind die Benutzer dafür selbst verantwortlich. Auch diese Aufgabe lässt sich mit Ansible vereinfachen. Das Homebrew Module verfügt hierfür über die Optionen update_homebrew, um Homebrew selbst zu aktualisieren und upgrade_all, um alle installierten Homebrew Pakete zu aktualisieren. Der dazugehörige Ansible Task sieht wie folgt aus.

- name: Update homebrew
  homebrew:
    update_homebrew: true
    upgrade_all: true

Ich füge einen solchen Update Task gerne am Anfang eines Playbooks ein, damit dieser jedes mal ausgeführt wird. Dadurch kann sichergestellt werden, dass Homebrew und alle von Homebrew installierten Pakete auf einem aktuellen Stand sind.

Konfigurationen vornehmen

Konfigurationen werden unter Linux und Mac OS in speziellen Konfigurationsdateien vorgenommen. Um Konfigurationen automatisch anzupassen können diese Dateien mit Ansible bearbeitet werden.

Es gibt unterschiedliche Möglichkeiten Konfigurationsdateien mit Ansible zu bearbeiten. Zum einen können Konfigurationsdateien erstellt werden, in dem diese an die richtige Stelle im System kopiert werden. Zum anderen können auch nur einzelne Zeilen zu einer bereits bestehenden Datei hinzugefügt werden. Zusätzlich gibt es noch viele weitere Möglichkeiten Konfigurationen vorzunehmen.

Beispielsweise haben wir eine (sehr) einfach gestaltete .zshrc Datei in unserem Ansible Setup, die bei erstmaliger Ausführung erstellt wird. Diese Datei beinhaltet lediglich einige praktische Aliase, um die tägliche Entwicklung zu vereinfachen.

alias ll='ls -la'

Diese .zshrc Datei wird mit folgendem Ansible Command in das Home Verzeichnis des Users kopiert mit der passenden Berechtigung, falls die Datei nicht bereits vorhanden ist.

- name: Create .zshrc if it does not exist
  copy:
    dest: ~/
    src: .zshrc
    mode: 0644
    force: no

Die andere Alternative, die wir für Konfigurationen verwenden ist eine zusätzlich Zeile zu einer Datei hinzuzufügen. Hierfür kann man das Ansible Module lineinfile verwendet werden. In unserem Ansible Setup nutzen wir dieses Module, um z.B. einen Hook für das Tool direnv in der .zshrc zu registrieren. Der Vorteil dieses Vorgehens im Vergleich zum Kopieren einer Konfigurationsdatei ist, dass sichergestellt ist, dass die Zeile in der Konfigurationsdatei vorhanden ist.

- name: Enable direnv
  lineinfile:
    path: ~/.zshrc
    line: eval "$(direnv hook zsh)"

Git Repos clonen und updaten

Insbesondere wenn man mit vielen Repos Git Repositories arbeiten muss, weil man beispielsweise einem Poly Repo Ansatz folgt oder an unterschiedlichen Projekten arbeitet verliert man schnell den Überblick. Mit Ansible kann man dem ein bisschen Abhilfe schaffen, in dem man die Git Repos in einem eigenen Task oder Playbook verwaltet.

Um Git Repos zu clonen und aktuell zu halten kann folgender Task definiert werden. Analog zu Homebrew Cask Installationen kann auch hier das with_items Feature verwendet werden. Zusätzlich sollte man zu diesem Task ignore_errors aktiviert werden, damit das Playbook nicht beendet wird sollte der Task fehlschlagen.

- name: Clone Miragon Git Repos
  git:
    repo: "git@github.com:Miragon/{{item}}.git"
    clone: yes
    update: yes
    dest: "~/source/miragon/{{item}}"
  ignore_errors: yes
  with_items:
    - code-examples

Sobald Uncommited Changes im Repository sind oder der Branch auf dem man sich aktuell befindet nicht existiert schlägt der Task fehl und das Playbook wird abgebrochen, wenn ignore_errors nicht aktiviert ist.

Ansible bei Miragon

In den vorangegangenen Abschnitten habe ich einen kurzen Überblick über Ansible gegeben habe und erklärt welche Ansible Module und Tasks wir bei Miragon verwenden, um Software auf unseren Macs zu installieren, aktuell zu halten und Git Repositories zu clonen. An dieser Stelle soll es jetzt noch konkreter werden, in dem ich erkläre, wie unser aktuelles Mac Setup aufgebaut ist und wie wir es verwenden.

Für unser Mac Setup verwenden wir Roles. Aktuell haben wir die beiden Playbooks initial.yml und site.yml.

Roles in Ansible sind eine Möglichkeit wiederverwendbare Bausteine zu definieren. Zusätzlich geben Roles eine Struktur für den Quellcode vor, die den Code übersichtlicher und verständlicher macht.

initial.yml für die Ersteinrichtung eines Macs

Das Playbook initial.yml nutzen wir für die Ersteinrichtung eines neuen Macbooks. Hierbei wird die Role mac auf jedem Mac und die Roles macdev und miragon zusätzlich nur auf Entwicklerpcs ausgeführt.

---
- hosts:
    - mac
  roles:
    - mac

- hosts:
    - macdev
  roles:
    - macdev
    - miragon

Die Role mac installiert mit Homebrew eine Auswahl an Standardprogrammen, die jeder von uns im täglichen Doing gebrauchen kann. Darunter fallen die Browser Firefox und Google Chrome, der Passwordmanager 1Password, die Office 365 Tools und der Window Manager Rectangle. Zusätzlich fügen wir auf dem Desktop des Users eine links.txt Datei hinzu mit den wichtigsten Links zu den Cloud Tools, die wir bei Miragon verwenden.

.
├── README.md
├── roles
│   ├── acs
│   │   ├── tasks
│   │   └── vars
│   ├── itm
│   │   ├── tasks
│   │   └── vars
│   ├── mac
│   │   └── tasks
│   ├── macdev
│   │   ├── files
│   │   ├── tasks
│   │   └── vars
│   ├── miragon
│   │   ├── tasks
│   │   └── vars
│   └── processide
│       ├── tasks
│       └── vars
├── initial.yml
└── site.yml

Die Role macdev funktioniert analog zur mac Role. Sie installiert zusätzlich eine Auswahl an Software mit Homebrew, die die Entwickler für ihre tägliche Arbeit benötigen. Darunter fallen bekannte Commandline Tools wie z.B. curl, wget, direnv, maven, gradle und die kubernetes-cli. Zusätzlich installieren wir die Java jdks, die wir aktuell für unsere Anwendungen verwenden sowie den Nodejs Versions Manager nvm.

Zudem führen wir auf Entwickler-PCs auch noch die Role miragon aus. Diese fügt einige allgemeine Git Repositories von Miragon auf dem PC in dem Ordner ~/source/miragon/ hinzu. Darunter fällt unsere Miragon Website, Code Beispiele und Templates sowie user Ansible Mac Setup.

site.yml für die alltägliche Nutzung

Nachdem das Playbook inital.yml sehr viel Zeit bei der Ausführung in Anspruch nehmen kann, habe ich mich dazu entschlossen für die alltägliche Nutzung ein eigenes Playbook anzulegen. Diese Playbook ist die site.yml und dient dazu Homebrew sowie die installierten Pakete aktuell zu halten und für unsere verschiedenen Projekte die Git Repositories zur Verfügung zu stellen.

---
- hosts:
    - mac
    - macdev
  tasks:
    - name: Update homebrew
      homebrew:
        update_homebrew: true
        upgrade_all: true
      ignore_errors: yes
- hosts:
    - macdev
    - miragon
  roles:
    - miragon
- hosts:
    - acs
  roles:
    - acs
- hosts:
    - itm
  roles:
    - itm
- hosts:
    - processide
  roles:
    - processide

Auch wenn jeder Entwickler Zugriff auf die vollständige Code Base von Miragon hat, braucht nicht jeder alle Projekte auf seinem PC für die täglich Arbeit. Deswegen legen wir für jedes Projekt eine eigene Role mit dem Projektnamen sowie einen Task in der site.yml an. Um diese Role auszuführen muss der User nur noch eine Gruppe mit dem Projektnamen im Inventory anlegen. Dadurch kann jeder Entwickler selbst entscheiden, von welchen Projekten er die Git Repositories clonen möchte.

Bei der Landeshauptstadt München sind wir Teil eines Entwicklungsteams, das die Prozessautomatisierungsplattform DigiWF entwickelt. Du möchtest mehr über DigiWF erfahren, dann schau dir gerne unseren Blog Post zu DigiWF bei der Landeshauptstadt München an.

Wenn beispielsweise ein Entwickler in unserm Kundenprojekt bei der Landeshauptstadt München startet, kann dieser folgende 2 Zeilen im Inventory hinzufügen und bekommt alle Repositories, die für das Projekt benötigt werden in den Ordner ~/source/miragon/itm/ gecloned.

[itm]
localhost ansible_user=<your-username> ansible_connection=local ansible_python_interpreter=python3

Tags

#miragon#ansible#IaC#mac
Previous Article
JSON Schema everywhere
Lukas Mösle

Lukas Mösle

Fullstack Entwickler

Inhalte

1
Was ist Ansible
2
Ansible trifft Mac
3
Ansible bei Miragon

Ähnliche Beiträge

Mehr in weniger Zeit - mit den richtigen Tools
June 08, 2020
4 min
© 2024, All Rights Reserved.

Links

StartseitePortfolioBPM TrainingÜber UnsKarriereBlog

Social Media