Ansible ist eine (Open-Source)-Software die ähnlich wie Cfengine oder Puppet Rechner von remote aus konfiguriert und verwaltet. Anders als Puppet wird auf dem Client keine spezielle Software benötigt, alles läuft über SSH.
Kleiner Nachteil: Ansible ist ein noch recht junges Projekt, bei Features und Konfigurationsoptionen kann sich auch mal konzeptuel was ändern.
Einige unten angeführten Beispiele funktionieren ohne Änderung z.B. nicht mehr ab Ansible 1.6, ab jetzt werden Variablen auch in den Playbooks (.yml) mit {
{ variable }}
aufgerufen (seit Version 1.2 zulässig), die alte Variante mit $variable
oder ${variable}
ist nicht mehr gültig, wird aber in vielen Beispielen noch aufgeführt.1)
Ab Ansible 2.0 gab es Änderungen bei sudo, dass heißt jetzt become … usw. Weshalb hier bei den neueren Text-Teilen auch immer dabeisteht, für welche Ansible-Version das gerade gilt *seufz*
/etc/hosts
o.ä. verteilen)
ansible all -m ping
ansible live -a "/bin/uname -a" afrika | success | rc=0 >> Linux afrika 3.2.0-33-generic #52-Ubuntu SMP Thu Oct 18 16:29:15 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux europa | success | rc=0 >> Linux europa 3.4.11-2.16-xen #1 SMP Wed Sep 26 17:05:00 UTC 2012 (259fc87) x86_64 x86_64 x86_64 GNU/Linux botswana | success | rc=0 >> Linux botswana 3.2.0-35-virtual #55-Ubuntu SMP Wed Dec 5 18:02:05 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
ansible all -m setup --tree ./facts
Szenario: Eine frisch geklonte virtuelle Linux-VM kennt noch nicht ihren neuen Hostname.
# /data/ansible/playbooks/all/etc-hostname.yml - hosts: all tasks: - name: set hostname on boot to short name from inventory list action: template src=/data/ansible/templates/etc_hostname.j2 dest=/etc/hostname owner=root group=root mode=0644 backup=yes register: hostname_file - name: change hostname on running system action: command hostname -F /etc/hostname # only_if: '${hostname_file.changed}' # only_if für Ansible-Versionen < 1.5 when: hostname_file.changed # Ansible-Versionen 1.5 und höher
/data/ansible/templates/etc_hostname.j2
sieht dann so aus:
{{ inventory_hostname_short }}
Damit ist der Name dann so gesetzt, wie er in im Inventory eingetragen ist (und bei Bedarf um die Domain gekürzt, wenn man den FQDN will, nimmt man "inventory_hostname" ).
Wenn man das dann nur bei dieser einen VM durchspielen will: Aufrufen über
ansible-playbook -l botswana /data/ansible/playbooks/all/etc-hostname.yml
In der Inventory-Datei (Ansible-Host-Datei) kann man seine Server in verschiedene Gruppen einteilen.
[kvmserver] afrika [kvmclients] botswana ansible_ssh_port=2222 ansible_ssh_host=192.168.10.22 mali ansible_ssh_port=2223 ansible_ssh_host=192.168.10.23 [ubuntuserver] afrika botswana mali [ubuntulive] afrika botswana [suseserver] europa [live] europa [live:children] ubuntulive [ubuntulaptops] tulpe
Normalerweise lagert man Aktionen, die nur für einzelne Gruppen gelten sollen, in einzelne Playbook- oder Task-Dateien aus. Im Header der Datei steht dann, für welche Rechner bzw. Gruppen das dann gilt: Statement "hosts" (z.B. - hosts: ubuntuserver
). Das Playbook gilt dann z.b. nur für ubuntuserver (siehe u.a. Playbook Language Example).
Wenn man ein paar Tasks nicht extra auslagern will2), kann man aber auch tasks mit Abhängigkeit zu einzelnen Bedingungen verknüpfen, z.B. eben der Gruppenabhängigkeit: :
--- - hosts: ubuntuserver tasks: # software kann man jede einzeln installieren: - name: install screen apt: pkg=screen state=installed - name: install vim apt: pkg=vim state=installed - name: install tree apt: pkg=tree state=installed # oder man macht eine Liste und installiert im Paket: - name: ensure kvm related software is installed via apt action: apt pkg=$item state=installed with_items: - qemu-kvm - libvirt-bin - virtinst - virt-top #when_string: '"kvmserver" in "$group_names"' ### <--- # SEHR ALTE Syntax (Ansible <1.2 oder so) when: "'kvmserver' in group_names"
(getestet mit Ansible 1.6 und 2.3)
Sicherer als sich überall mit root einzuloggen: Man verwendet personalisierte Accounts und nützt sudo für Admin-Aktionen.
Das geht auch bei ansible, man muss dann nur sagen als wer man
sich einloggen will: --user meinusername
,
und dass man
bitte immer nach dem sudo-password gefragt werden will: --ask-sudo-pass
(ab 1.9 --ask-become-pass
, kurz -K
)
Beispiel:
Die Rechner in der Gruppe "suseserver" werden weiterhin mit dem User root administriert. Bei "ubuntuserver" werden personalisierte Accounts und sudo verwendet.
Hier das Ende der Inventory-Datei
... # personalisierte Useraccounts fuer Hosts in den der Gruppe "ubuntuserver" [admin_users:children] ubuntuserver # User root fuer for Server in diesen Gruppe "suseserver" [user_root:children] suseserver
Beispiel-Aufruf :
# Version 1.6 ansible-playbook --user bnutzer --ask-sudo-pass -l mali pfad/zum/playbook.yml sudo password: # Version 1.9 und höher ansible-playbook --user bnutzer --ask-become-pass -l mali pfad/zum/playbook.yml SUDO password:
Damit dann auf der entfernten Maschine auch sudo verwendet wird, muß Ansible das dann auch noch mitgeteilt werden.
Dafür gibt es 2 Möglichkeiten:
# ALT! ansible-playbook --user bnutzer --sudo --ask-sudo-pass -l mali pfad/zum/playbook.yml ## ACHTUNG ALT # Version 1.9 und neuer: ansible-playbook --user bnutzer --become --ask-become-pass -l mali pfad/zum/playbook.yml # Version 1.9 in kurz ansible-playbook -u bnutzer -b -K -l mali pfad/zum/playbook.yml
--- - hosts: #sudo: yes #alt become: true # ab 1.9
Wenn man überall den selben User verwendet, kann man sich die Tipparbeit für --user bnutzer
sparen, in dem man den Login-User in der $HOME/.ansible.cfg
hinterlegt:
remote_user=bnutzer
(getestet mit Ansible 1.6 und 2.3)
Nachteil an --ask-sudo-pass
(bzw. --ask-become-pass
): bei jedem Ansible-Lauf muss man immer
neu das sudo-Passwort eingeben. Auch wenn man dann höllisch gut
drauf aufpassen muss, kann man das nicht irgendwo abspeichern?
Antwort: Man kann, sollte diese Datei aber am besten auf einer verschlüsselten Partition speichern und nur mit symbolischem Link an die richtige Stelle verlinken. Und -- ganz wichtig -- diese Datei davor schützen, dass sie in der Versionsverwaltung landet! (.gitignore o.ä.)
--- # group_vars/admin_users/sudopass # sudo_pass ist abgekündigt ab 1.9, aber wir haben evtl noch alte playbooks die das verwenden (und bisher teilweise auch noch funktionieren): ansible_sudo_pass: Main!Sicheres99Kennwort # ansible_become_pass fuer ansible-Versionen >= 1.9 ansible_become_pass: Main!Sicheres99Kennwort
Beispiel-Aufruf:
ansible-playbook --user bnutzer -l mali pfad/zum/playbook.yml
Hintergrund: ansible_sudo_pass
gehört zu den Inventory Variablen, die das Verhalten von Ansible steuern. Ansible Group Variablen kann man in eigene Dateien auslagern.
(getestet mit Version 2.3)
ansible localhost -m debug -a 'var=groups.keys()'
zeige zusätzlich die in diese Gruppen gehörigen Server:
ansible localhost -m debug -a 'var=groups'
Quelle: http://stackoverflow.com/questions/33363023/is-there-any-option-to-list-groups-in-ansible
getestet mit Ansible 2.3.1
Das Monitoring schimpft: swap ist aus! Ist zwar nicht (immer) so schlimm, aber Plattenplatz hätten wir … also einfach ein zweites Swapvolume anlegen im LVM …
# hosts.swap - ein eigenes inventory file nur fuer die erweiterung vom swap # parameter: # vgname -> namen von volume groups sind nicht einheitlich ... # swlv -> name des neuen swap logical volumes # size -> groesse des neuen swap logical volumes [admin_users] # log dich bei diesem servern mit eigenem user ein (und mach bei bedarf sudo bzw. -b) brasilien vgname=vgdata swlv=swap size=2G chile vgname=vg00 swlv=swap2 size=2G suedamerika vgname=vg00 swlv=swap2 size=8G
$ ansible all -i ./hosts.swap -m shell -a "lvcreate -n {{ swlv }} -L{{ size }} {{ vgname }}" -b $ ansible all -i ./hosts.swap -m shell -a "mkswap /dev/{{ vgname }}/{{ swlv }}" -b $ ansible all -i ./hosts.swap -m mount -a "src=/dev/{{ vgname }}/{{ swlv }} path=swap fstype=swap opts=sw passno=0 dump=0 state=present" -b
[WARNING]: Platform linux on host botswana is using the discovered Python interpreter at /usr/bin/python, but future installation of another Python interpreter could change this. See https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.
oder
DEPRECATION WARNING]: Distribution Ubuntu 18.10 on host mali should use /usr/bin/python3, but is using /usr/bin/python for backward compatibility with prior Ansible releases. A future Ansible release will default to using the discovered platform python for this host. See https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information. This feature will be removed in version 2.12. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg
Weil Ansible aber sehr schnell mal ein paar Features "deprecated", will man die Deprecation Warnings lieber nicht ausschalten.
Deshalb nur die Python-Versionserkennung auf leise stellen in der Ansible-Config (z.B. in der .ansible.cfg):
[default] interpreter_python=auto_silent
when_string
&. Co zu when
fehlt leider)
gilt für alle Tipps, Tricks & Spickzettel:
dies sind einfache, teils banale Notizen für meinen persönlichen Gebrauch,
die hier eher zufällig auch öffentlich lesbar sind
(vielleicht hilft es ja jemandem weiter). Verwendung auf eigene Gefahr
Fehler-Hinweise, Dankesschreiben , etc. bitte an: web.21@unixwitch.de
weitere Tools / Spickzettel