Introduzione ad Ansible

Cos’è Ansible: Ansible è uno strumento open source per l'automazione. Fornisce una piattaforma semplice, agentless e potente che permette di automatizzare tutti i processi di una infrastruttura indipendentemente dal tipo di infrastruttura e dal tipo di processo. La sua flessibilità e versatilità lo rendono lo strumento giusto per gestire casi di utilizzo che tipici come: • Provisioning • Configuration Management • Application Deployment • MultiTier Orchestration Perché Ansible: Una caratteristica fondamentale Ansible è l’essere agentless: i requisiti sono solamente ssh e python (ormai installato di default in ogni sistema unix like). Non ha bisogno di agenti remoti, Ansible autonomamente trasferisce moduli ed esegue task nel sistema remoto dei quali ha bisogno inoltre pulisce l’ambiente quando ha terminato. Ansible ha una serie di vantaggi che lo rendono migliore rispetto ai competitor: • è idempotente ,una volta eseguito correttamente un task possiamo rilanciarlo più volte ma tale task non sarà eseguito di nuovo • non ho bisogno di un ulteriore server (da configurare e gestire a sua volta) per configurare e gestire i miei server • sfrutta il sistema di autenticazione già esistente: ssh. Non ho bisogno di installare nè di integrare un ulteriore sistema di autenticazione aggiungendo inutili strati ulteriori • necessita solo di python, installato ormai di default in ogni sistema unix like • non necessita la conoscenza di specifici linguaggi di programmazione per poterlo usare • è di facile adozione in quanto estremamente semplice • è estendibile via moduli • tutti i file di configurazione sono di tipo YAML quindi modificabili semplicemente con qualsiasi editor di testo Fondamenti: Inventory: È il file che contiene tutte le informazioni strutturate dei vostri server. [web] vg01.ibuildings.ws vg02.ibuildings.ws [db] vg03.ibuildings.ws Specificando “web” andremo ad eseguire le operazioni solo sui server vg01 e vg02, specificando “db” esegueremo l’operazione solo in vg03 mentre specificando la keyword “all” eseguiremo l’operazione su tutti i server. → ansible all i hosts m ping vg01 \| success >> {“changed“: false,“ping“: “pong“ } vg02 \| success >> { “changed“: false, “ping“: “pong“} vg03 \| success >> { “changed“: false, “ping“: “pong“} Abbiamo eseguito su tutti i server all specificati nel file di inventory host il modulo ping (che pinga i server per vedere se sono raggiungibili). Variables: Sono variabili definite dal sistema, dall’utente o ricavate in real time che possono essere usate da Ansible. → cat group_vars/all ansible_ssh_user: vagrant ansible_become: true Istruisce Ansible ad usare l’utente vagrant per connettersi via ssh ed ad usare sudo per eseguire tutti i comandi. Le variabili possono essere specificate anche nei task per essere poi usate successivamente dalle altre istruzioni o templates. Tasks: Combina un’azione (formata da un modulo ed i suoi argomenti) con un nome ed eventualemente altri parametri opzionali name: Install Apache2 apt: name=apache2 state=present “apt” è un modulo e serve per gestire pacchetti in sistemi debian like. Nello specifico controlla se apache2 è installato ed in caso negativo lo installa. “get_url” è un altro modulo, nell’esempio successivo è usato per scaricare drush ed inserirlo nella directory giusta con i permessi corretti. name: Download and install drush get_url: url=http://files.drush.org/drush.phar dest=/usr/local/bin/drush mode=0755 Templates: Sono file parsati da Ansible che sostituirà le variabili necessarie quando necessario. → cat roles/mysqlserver/templates/.my.cnf [client] user=root password={{ mysql_root_pass }} La variabile “mysql_root_pass” nel template sarà sostituita dal valore specificato in questo caso nel play (ma potevo specificarlo anche a riga di comando). # install mysqlserver hosts: db roles: mysqlserver drupaldb vars: mysql_root_pass: toor mysql_drupal_db: drupal mysql_drupal_user: drupal mysql_drupal_pass: drupal tags: mysqlserver Nota: Le sostituzioni delle variabili vengono effettuate anche nelle altre istruzioni come i task e non solo nei file di templates. name: create db for drupal mysql_db: name=drupal state=present login_user=root login_password=“{{ mysql_root_pass }}“ collation=utf8mb4_unicode_ci encoding=utf8mb4 Il task precedente crea un db di nome “drupal” specificando collation ed encoding. Per far questo ha bisogno delle credenziali di accesso al db, l’utente è root standard mentre la password è contenuta in una variabile. Handlers: Esegue un’azione quando specificato. Il seguente task copia il file di configurazione di nginx e notifica l’handler “restart nginx” name: template configuration file template: src=nginx.conf dest=/usr/local/nginx/nginx.conf notify: restart nginx L’handler “restart nginx” è ovviamente: name: restart nginx service: name=nginx state=restarted Da notare che anche “service” è un modulo. Tags: Servono a specificare un particolare play, role o task. # install web deps hosts: web roles: web drupal tags: web Roles: Sono unità di organizzazione di Ansible, contengono tasks, templates, variables, etc. Sono utili perchè permettono di: • dividere la configurazione in più pezzi riutilizzabili tra vari progetti • mantenere una struttura pulita • condivisione su Ansible Galaxy • riusabili e riciclabili La struttura di un role è organizzata come segue: roles/ nginx/ tasks/ main.yml handlers/ main.yml templates/ nginx.conf mysite.conf files/ bar.txt foo.sh vars/ main.yml defaults/ main.yml Playbooks: Un playbook è un gruppo di play. Il play rappresenta il mapping tra un insieme di host e le istruzioni che saranno eseguite in quegli host. vars: http_port: 80 remote_user: root tasks: name: ensure nginx is at the latest version yum: name=nginx state=latest name: write the nginx config file template: src=nginx.conf dest=/usr/local/nginx/nginx.conf notify: restart nginx name: ensure nginx is running (and enable it at boot) service: name=nginx state=started enabled=yes handlers: name: restart nginx service: name=nginx state=restarted Il playbook di esempio eseguirà tutti i task specifici negli host definiti come “webservers” nel file di inventory. L’esempio specifico è a titolo esemplificativo e non è una best practice in quanto è consigliabile dividere i task in role. hosts: webservers vars: http_port: 80 roles: nginx phpfpm hosts: dbservers roles: mysql I playbook si eseguono semplicemente attraverso l’istruzione: ansibleplaybook example_playbook.yml vvvv Note: Un modulo utile è “command” che permette di eseguire comandi arbitrati negli host specificati. → ansible all i hosts m command a “whoami“ vg01 | success | rc=0 >> root vg02 | success | rc=0 >> root vg03 | success | rc=0 >> root Playbook di esempio: All’indirizzo https://github.com/and9000/ansible_example è presente un playbook di esempio funzionante. Tale playbook configura 2 macchine, vg01 come server web installando apache, php e drupal e vg02 come db server installandoci mysql. Ovviamente è possibile modificando il file di inventory “hosts” cambiare il nome delle macchine. La struttura è la seguente: hosts roles drupaldb templates my.cnf tasks main.yml drupal tasks main.yml mysqlserver  templates my.cnf tasks main.yml handlers main.yml web tasks main.yml handlers main.yml mysqlclient tasks main.yml example_playbook_1.yml group_vars all Nel file di hosts sono specificate le macchine interessate: → cat hosts [web] vg01 [db] vg02 Nello specifico sono 2 macchine su vagrant configurate correttamente per l’accesso con chiave per l’utente vagrant. Ansible poi userà sudo per eseguire tutti i comandi necessari. → cat group_vars/all ansible_ssh_user: vagrant ansible_become: true Il playbook è eseguito con: → ansibleplaybook i hosts example_playbook_1.yml Una corretta esecuzione produrrà al termine dell’output le seguenti righe: PLAY RECAP ******************************************************************** vg01 : ok=10 changed=7 unreachable=0 failed=0 vg02 : ok=12 changed=8 unreachable=0 failed=0 Eseguendo nuovamente il playbook si nota che non viene più eseguito nessun task in quanto sono tutti terminato correttamente precedentemente e non sono stati modificati: PLAY RECAP ******************************************************************** vg01 : ok=9 changed=0 unreachable=0 failed=0 vg02 : ok=11 changed=0 unreachable=0 failed=0 Playbook: → cat example_playbook_1.yml # install web deps hosts: web roles: web drupal tags: web # install mysqlclient hosts: web:db roles: mysqlclient tags: mysqlclient # install mysqlserver hosts: db roles: mysqlserver drupaldb vars: unreachable=0 unreachable=0 failed=0 failed=0 mysql_root_pass: toor mysql_drupal_db: drupal mysql_drupal_user: drupal mysql_drupal_pass: drupal tags: mysqlserver Ci sono 5 role: • web (installa apache, php, etc.) • mysqlclient (installa mysqlclient) • mysqlserver (installa mysqlserver) • drupal (installa drupal) • drupaldb (crea il db e l’utente per drupal) Ogni ruolo è eseguito solamente negli host necessari, specificando le variabili d’ambiente utili (per esempio quelle del db). Inoltre sono presenti tag per permettere l’esecuzione selettiva dei play. Alla fine dell’esecuzione all’indirizzo “http://vg01/drupal” sarà presente un drupal scaricato pronto per l’installazione con il db già creato (i dati relativi alla connessione sono impostati tramite variabili). Conclusioni: Ansible semplicemente è uno strumento che permette di automatizzare qualsiasi processo in qualsiasi sistema. Abbraccia Ansible:batteries included!
Realizziamo qualcosa di straordinario insieme!
Siamo consulenti prima che partner, scrivici per sapere quale soluzione si adatta meglio alle tue esigenze. Potremo trovare insieme la soluzione migliore per dare vita ai tuoi progetti.