Zoals gezegd, bij complexere omgevingen is het verstandig om een structuur aan te brengen op de Ansible master. In feite kan dit vanuit elke directory zijn en we maken een structuur in de /apps/ansible/ directory. Deze ziet er alsvolgt uit:
. ├── group_vars └── roles ├── common │ ├── handlers │ ├── tasks │ └── templates └── musicplayers ├── handlers ├── tasks └── templates
In de hoofd-directory (/apps/ansible/) maken we een bestand genaamd ‘musicplayers‘ waarin we de host-specificaties zetten. Dit bestand vervangt dan het algemene /etc/ansible/hosts bestand. De inhoud is hetzelfde, namelijk een alias, het IP adres van de node en de gebruiker op de nodes waarmee we de instructies geven. Deze gebruiker heeft dan onze publieke sleutel in de authorized_keys staan.
[musicplayers] huiskamer ansible_host=192.168.1.31 ansible_user=ansible demoruimte ansible_host=192.168.1.21 ansible_user=ansible badkamer ansible_host=192.168.1.41 ansible_user=ansible #tuin ansible_host=192.168.1.51 ansible_user=ansible
In deze directory staat ook het playbook, genaamd musicplayers.yml met de volgende inhoud:
--- # This playbook deploys the whole application stack in this site. - name: apply common configuration to all nodes hosts: all roles: - common - name: configure and deploy the musicplayer nodes hosts: musicplayers roles: - musicplayers
Wat we hiermee aangeven is dat op alle nodes (all) de roles uit de ‘common‘ directory uitgevoerd moeten gaan worden en op de nodes van de groep ‘musicplayers‘ willen we de roles uit de directory ‘musicplayers‘ uit voeren.
Roles
Nu volgt een directory genaamd ‘roles‘ waarin subdirectories staan. Deze kun je vergelijken met de ‘manifests’ in puppet. We hebben ‘common‘ voor alle nodes en ‘musicplayers‘ voor onze muziek-streamers.
Tasks
Per role staat onder andere de ‘tasks‘ directory. In roles/common/tasks/ vinden we main.yml met de volgende inhoud:
--- # this is the common playbook for all nodes - name: Install ntp yum: name=ntp state=present tags: ntp - name: Configure ntp file template: src=ntp.conf.j2 dest=/etc/ntp.conf tags: ntp notify: restart ntp - name: Start the ntp service service: name=ntpd state=started enabled=yes tags: ntp
Een aantal zaken vallen hier op, te beginnen met de tags: aanduiding. Hiermee kunnen we de 3 losse taken tot één geheel maken. Het playbook zou dan uitgevoerd kunnen worden met de optie –tags: “ntp”. Naast de yum-instructie (of ‘apt’ op Ubuntu/Debian systemen) die feitelijk voor zichzelf spreekt zien we template: en notify:
template: gebruikt een template-bestand die terug te vinden is in de ‘templates‘ directory. De ‘dest’ geeft aan waar het uiteindelijk bestand moet komen.
notify: is een trigger-instructie die een bepaalde handler zal activeren. Deze staat dan in de ‘handlers‘ directory.
Tasks kunnen ook ge-nest worden en dat kan met ‘include_tasks’ of ‘import_tasks’. Het verschil hiertussen is dat import_tasks de tasks-list van te voren al in laadt en met include_tasks worden de taken geladen op het moment dat de include-instructie aan de beurt is. Een voorbeeld:
# Include OS specific tasks - include_tasks: CentOS.yml when: ansible_distribution == "CentOS" - include_tasks: Ubuntu.yml when: ansible_distribution == "Ubuntu"
Templates
De template die we gebruiken voor de ntp-service heeft de volgende inhoud:
driftfile /var/lib/ntp/drift restrict 127.0.0.1 restrict -6 ::1 server {{ ntpserver }} includefile /etc/ntp/crypto/pw keys /etc/ntp/keys
Group variables
Er wordt hier gebruik gemaakt van een group-variable en deze is terug te vinden (vanuit de hoofd-directory) in de subdirectory ‘group_vars‘. Hier staat een bestand genaamd ‘all‘ met de volgende inhoud:
--- # Variables listed here are applicable to all host groups ntpserver: 0.nl.pool.ntp.org
Hier kunnen uiteraard nog meer time-servers opgegeven worden maar het gaat even om het idee. Rest nog de handler:
Handlers
Om de service te kunnen herstarten nadat de config-file is aangepast laten we een handler dit werk doen. Deze staat dus in de handlers directory en heet ook hier ‘main.yml‘ met de volgende inhoud:
--- # Handler to handle common notifications. Handlers are called by other plays. # See http://docs.ansible.com/playbooks_intro.html for more information about handlers. - name: restart ntp service: name=ntpd state=restarted
De naam is in de notify: regel van de task gedefinieerd en komt overeen met de name:, namelijk ‘restart ntp‘
Samengevat ziet de roles/common-tree er dan zo uit:
. ├── handlers │ └── main.yml ├── tasks │ └── main.yml └── templates └── ntp.conf.j2
Specifieke configuraties en services (lees: tasks) worden verder beheerd in de musicplayers-role waarbij de structuur gelijk is aan de common-role.
Bijvoorbeeld modules voor sudoers, een motd-bestand, mail-functies, crontab jobs, etc… maar dat is voor een volgende keer…
Mochten er trouwens bestanden op de nodes gekopieerd moeten worden dan kan per role nog voor dit doel een ‘files‘ directory gemaakt worden.
Ansible-playbook
Om nu dit playbook uit te voeren op de musicplayers geven we vanuit de hoofd-directory /apps/ansible/ het volgende commando:
ansible-playbook -i musicplayers musicplayers.yml
De optie ‘-i musicplayers’ zorgt ervoor dat het juiste hosts-bestand wordt aangeroepen.
Resultaat
PLAY [apply common configuration to all nodes] ****************************************************************************************************** TASK [Gathering Facts] ****************************************************************************************************************************** ok: [huiskamer] ok: [demoruimte] ok: [badkamer] TASK [common : Install ntp] ************************************************************************************************************************* ok: [huiskamer] ok: [demoruimte] ok: [badkamer] TASK [common : Configure ntp file] ****************************************************************************************************************** ok: [huiskamer] ok: [demoruimte] ok: [badkamer] TASK [common : Start the ntp service] *************************************************************************************************************** ok: [huiskamer] ok: [demoruimte] ok: [badkamer] PLAY [configure and deploy the musicplayer nodes] *************************************************************************************************** TASK [Gathering Facts] ****************************************************************************************************************************** ok: [huiskamer] ok: [demoruimte] ok: [badkamer] PLAY RECAP ****************************************************************************************************************************************** badkamer : ok=5 changed=0 unreachable=0 failed=0 demoruimte : ok=5 changed=0 unreachable=0 failed=0 huiskamer : ok=5 changed=0 unreachable=0 failed=0
Hieraan is te zien dat op alle nodes de ntp-service al geïnstalleerd was, zie ‘changed=0’. Hoe dan ook, het playbook is succesvol uitgevoerd!
Indien je een nieuw project start dan is het mogelijk dat je Ansible de directory structuur laat aanmaken. Dit kan voor bijvoorbeeld het project ‘projectnaam‘ met het volgende commando:
ansible-galaxy init projectnaam
De structuur die aangemaakt wordt ziet er dan als volgt uit:
. ├── defaults ├── files ├── handlers ├── meta ├── tasks ├── templates ├── tests └── vars