Gitolite mit ansible-playbook post-update hook zum Verteilen von Konfigurationen etc.

Gitolite ist ein einfaches Script um einen GIT Repo Server aufzusetzen. Zusammen mit Ansible nutze ich es um z.B. Zonenfiles auf Bind9 Server zu verteilen. Das werde ich in diesem Beispiel zeigen. Ansible und Gitolite laufen auf dem gleichen Server.

Installation Gitolite

apt install gitolite3

Während der Installation wird nach dem Public SSH Key des Admins gefragt. Dieser Key ist später berechtigt das gitolite-admin Repo welches die Konfiguration der Repos beinhaltet zu benutzen.

Klonen von gitolite-admin und neues Repo dns anlegen

git clone gitolite3@10.1.1.1:gitolite-admin

gitolite-admin/conf/gitolite.conf

repo gitolite-admin
    RW+    =     admin

repo testing
    RW+    =     @all

repo dns
    option hook.post-update = dns-deploy
    RW+    =     admin

Hier wurde bereits ein post-update Hook definiert. Es müssen aber noch weitere Einstellungen angepasst werden damit dieser funktioniert.

Neue User legt man an in dem Verzeichnis gitolite-admin/keydir <username>.pub mit dem entsprechenden SSH Key anlegt. Die Usernamen können dann in der gitolite.conf verwendet werden. Ausführliche Doku zu gitolite -> http://gitolite.com/gitolite/index.html

Installation ansible 

apt install software-properties-common
apt-add-repository ppa:ansible/ansible
apt update
apt install ansible

Konfiguration ansible

Ich verwende auf den Zielsystemen eigene User um Dinge per Ansible zu deployen. Im Beispiel heist der „vader“.

/etc/ansible/hosts

[dns-servers]
ns1.example.com
ns2.example.com

/etc/ansible/group_vars/dns-servers

---
ansible_ssh_private_key_file: /etc/ansible/sshkey/id_rsa
ansible_ssh_user: vader
ansible_sudo_pass: lukeiamyourfather

SSH Key für vader erzeugen

mkdir -p /etc/ansible/sshkey
ssh-keygen -t rsa -f /etC/ansible/sshkey/id_rsa

Den SSH Key ohne Passwort ablegen.

Anpassen der Verzeichnis Rechte:

chmod 600 /etc/ansible/sshkey
chmod 600 /etc/ansible/sshkey/id_rsa
chmod 644 /etc/ansible/sshkey/id_rsa.pub
chown root:root -R /etc/ansible/sshkey

Auf den Zielsystemen muss jeweils der User vader mit dem Passwort eingerichtet werden und der Public Key des SSH Keys muss als authorized_key hinterlegt werden. Der User muss in der sudo Gruppe sein.

gitolite hook aktivieren

/var/lib/gitolite3/.gitolite.rc

Bei folgenden Zeilen Kommentierung entfernen.

LOCAL_CODE                =>  "$ENV{HOME}/local",

# allow repo-specific hooks to be added
            'repo-specific-hooks',

Verzeichnis anlegen für Hooks

mkdir -p /var/lib/gitolite3/local/hooks/repo-specific

dns-deploy hook anlegen

/var/lib/gitolite3/local/hooks/repo-specific/dns-deploy

sudo /opt/ansible/dns.sh

Owner und Rechte ändern

chown gitolite3:gitolite3 dns-deploy
chmod +x dns-deploy

Das Hook Script liegt in /opt/ansible:

mkdir -p /opt/ansible

/opt/ansible/dns.sh

#!/bin/bash


REPO=/opt/ansible/dns

if [ ! -d $REPO ]
then
   ssh-agent bash -c 'ssh-add /etc/ansible/sshkey/id_rsa; git clone gitolite3@10.1.1.1:dns'
else
    cd $REPO
    ssh-agent bash -c 'ssh-add /etc/ansible/sshkey/id_rsa; git pull'
fi


cd $REPO
ansible-playbook dns.yaml

# End

Das Hook Script klont das Repo dns nach /opt/ansible/dns und führt das ansible playbook aus dem Repo aus.

Anpassen der Rechte

chown root:root /opt/ansible/dns.sh
chmod 700 /opt/ansible/dns.sh

Den gitolite3 User berechtigen das Script ohne Passwort per Sudo auszuführen

/etc/sudoers

gitolite3 ALL = (root) NOPASSWD: /opt/ansible/dns.sh

Das Repo dns

git clone gitolite3@10.1.1.1:dns
cd dns

Anlegen des Playbooks

dns.yaml

---

- hosts: dns-servers

  tasks:

  - name: create or update named.conf.local
    become: true
    register: named
    template:
      src: /opt/ansible/dns/conf/named.conf.local.j2
      dest: /etc/bind/named.conf.local
    vars:
      zones:
      - lanbugs.de

  - name: create or update zone files
    become: true
    register: zones
    template: src={{ item }} dest=/etc/bind/{{ item | basename | regex_replace('\.j2','') }} owner=root group=root mode=0644
    with_fileglob:
      - /opt/ansible/dns/conf/db.*.j2

  - name: restart bind
    become: true
    service:
      name: bind9
      state: restarted
    when: zones.changed or named.changed

DNS Files

mkdir conf

named.conf.local.j2

{% for zone in zones %}
zone "{{ zone }}" {
    type master;
    file "/etc/bind/db.{{ zone}}";
};
{% endfor %}

db.lanbugs.de.j2

; BIND db file for lanbugs.de

$TTL 86400

{% include "zone_header.j2" %}

@               1800    IN      TXT     "v=spf1 a mx ptr ~all"

test            1800    IN      A       1.2.3.4


$ORIGIN lanbugs.de.

zone_header.j2

@       IN      SOA     ns1.example.com.      admin.example.com. (
                        2018111101      ; serial number YYMMDDNN
                        28800           ; Refresh
                        7200            ; Retry
                        864000          ; Expire
                        86400           ; Min TTL
                        )

@       1800    IN      NS      ns1.example.com.
@       1800    IN      NS      ns2.example.com.

@       1800    IN      MX      10 mail1.example.com.
@       1800    IN      MX      20 mail2.example.com.

Files zu dns Repo hinzufügen und pushen

git add -A
git commit -m "initial commit"

git push
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 311 bytes | 311.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Identity added: /etc/ansible/sshkey/id_rsa (Ansible vader)
remote: From 10.1.1.1:dns
remote:    63bf7b0..63d2dc5  master     -> origin/master
remote: Updating 63bf7b0..63d2dc5
remote: Fast-forward
remote:  conf/db.lanbugs.de.j2 | 1 -
remote:  1 file changed, 1 deletion(-)
remote: 
remote: PLAY [dns-servers] *************************************************************
remote: 
remote: TASK [Gathering Facts] *********************************************************
remote: ok: [ns1.example.com]
remote: ok: [ns2.example.com]
remote: 
remote: TASK [create or update named.conf.local] ***************************************
remote: ok: [ns1.example.com]
remote: ok: [ns2.example.com]
remote: 
remote: TASK [create or update zone files] *********************************************
remote: changed: [ns1.example.com] => (item=/opt/ansible/dns/conf/db.lanbugs.de.j2)
remote: changed: [ns2.example.comc] => (item=/opt/ansible/dns/conf/db.lanbugs.de.j2)
remote: 
remote: TASK [restart bind] ************************************************************
remote: changed: [ns1.example.com]
remote: changed: [ns2.example.com]
remote: 
remote: PLAY RECAP *********************************************************************
remote: ns1.example.com        : ok=4    changed=2    unreachable=0    failed=0   
remote: ns2.example.com        : ok=4    changed=2    unreachable=0    failed=0   
remote: 
To 10.1.1.1:/dns
   63bf7b0..63d2dc5  master -> master

Have fun 🙂

 

 

 

 

 

Schreibe einen Kommentar

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.