setup ambiente
per proseguire le nostre prove con ansible, ci prepariamo una macchina virtuale usando Vagrant:
$ vagrant box add centos http://www.lyricalsoftware.com/downloads/centos65.box $ vagrant init centos $ vagrant up |
a seguito dell’ultimo comando, vedremo dei messaggi come questi:
[default] Importing base box 'centos'... [default] Matching MAC address for NAT networking... [default] Setting the name of the VM... [default] Clearing any previously set forwarded ports... [default] Clearing any previously set network interfaces... [default] Preparing network interfaces based on configuration... [default] Forwarding ports... [default] -- 22 => 2222 (adapter 1) [default] Booting VM... [default] Waiting for machine to boot. This may take a few minutes... [default] Machine booted and ready! [default] Mounting shared folders... [default] -- /vagrant
Vagrant ha scaricato e creato per noi una macchina virtuale Centos (per default con Virtualbox).Scorrendo i messaggi ci sono due cose importanti da notare: la prima è che il traffico sulla porta 2222 del nostro pc locale sarà inoltrato alla porta 22 della macchina virtuale; la seconda è che l’utente “vagrant” sulla macchina remota può connettersi con la password “vagrant” ed ha già i privilegi per diventare root con sudo. Aggiorniamo quindi il nostro inventario:
$ sudo bash -c 'echo [web] >> /etc/ansible/hosts' $ sudo bash -c 'echo 127.0.0.1:2222 ansible_ssh_user=vagrant ansible_ssh_pass=vagrant >> /etc/ansible/hosts' |
abbiamo creato un nuovo gruppo di macchine, ed in questo gruppo inseriamo per il momento solo un server, con i parametri per collegarsi. Qui scriviamo la password in chiaro per motivi didattici, ma in qualsiasi altro contesto è necessario configurare il login ssh tramite chiave pubblica/privata.
ripetiamo ora il test del ping verso la/le VM:
$ ansible web -m ping |
127.0.0.1 | success >> { "changed": false, "ping": "pong" }
Ansible facts
come possiamo essere sicuri che la macchina a cui ci stiamo connettendo sia quella giusta ? Diamo un’occhiata ai “facts”, ovvero a tutte le informazioni che Ansible raccoglie…
$ ansible web -m setup | less |
otteniamo una serie di dati in formato JSON tra cui notiamo che il nostro nuovo server ha come hostname ‘localhost’… Possiamo sfruttare ansible per sistemarlo, e ne approfittiamo per preparare il nostro
primo playbook
$ cat configura_hostname_1.yml |
--- #questo playbook serve per configurare il nome degli host - name: configura hostname hosts: web remote_user: root tasks: - hostname: name=web01
lo mandiamo in esecuzione con il comando apposito
$ ansible-playbook configura_hostname_1.yml |
PLAY [configura hostname] ***************************************************** GATHERING FACTS *************************************************************** ok: [127.0.0.1] TASK: [hostname name=web01] *************************************************** changed: [127.0.0.1] PLAY RECAP ******************************************************************** 127.0.0.1 : ok=2 changed=1 unreachable=0 failed=0
è importante notare che i playbook sono idempotenti, cioè ad ogni esecuzione il risultato è sempre il medesimo. Sostanzialmente quando scriviamo un playbook definiamo lo stato finale del nostro sistema, cioè come vogliamo che diventi.
Miglioriamo il playbook
Abbiamo volutamente portato un esempio un po’ forzato, in quanto non è buona norma configurare lo stesso nome su tutti i server 🙂 Per cui dovremmo scrivere un playbook del genere con parametri, prendendo delle variabili e associandole al nostro server. Ad esempio adotteremo la convenzione che tutte le macchine nella nostra serverfarm immaginaria dovranno chiamarsi concatenando il nome della propria distribuzione e il macaddress della scheda di rete (togliendo il carattere ‘:’ in quanto non ammesso), così da generare un nome univoco.
cat configura_hostname_2.yml |
--- #questo playbook serve per configurare il nome degli host in modo univoco - name: configura hostname secondo la convenzione distro+mac_address hosts: all remote_user: root sudo: yes tasks: - hostname: name="{{ansible_distribution}}{{ansible_default_ipv4.macaddress|regex_replace(':', '')}}"
la riga che usa il modulo ‘hostname’ è leggermente cambiata: abbiamo inserito tra doppie graffe la prima variabile {{ansible_distribution}} che viene valorizzata automaticamente da Ansible con il nome della nostra distribuzione (nel nostro caso quindi diventerà “CentOS”) e di seguito una piccola operazione: prendiamo il macaddress della scheda di rete principale (sempre fornitoci da Ansible) e lo “filtriamo” con una regular expression, in modo da togliere il carattere ‘:’. Otteniamo quindi una stringa numerica esadecimale.
Lanciamo il playbook
$ ansible-playbook configura_hostname_2.yml |
PLAY [configura hostname secondo la convenzione distro+mac_address] *********** GATHERING FACTS *************************************************************** ok: [127.0.0.1] TASK: [hostname name="{{ansible_distribution}}{{ansible_default_ipv4.macaddress|regex_replace(':', '')}}"] *** changed: [127.0.0.1] PLAY RECAP ******************************************************************** 127.0.0.1 : ok=2 changed=1 unreachable=0 failed=0
Se avessimo usato una Debian o una Suse non avremmo dovuto cambiare il nostro playbook: Ansible si occupa dei dettagli relativi ad ogni distribuzione!
Per assicurarci del risultato, ci basta fare una semplice verifica direttamente sulla macchina virtuale:
$ vagrant ssh |
Welcome to your Vagrant-built virtual machine. [vagrant@CentOS0800274bab3f ~]$ cat /etc/sysconfig/network NETWORKING=yes HOSTNAME=CentOS0800274bab3f [vagrant@CentOS0800274bab3f ~]$ hostname CentOS0800274bab3f
per il momento ci riteniamo soddisfatti del risultato… Nel prossimo articolo approfondiremo l’argomento scrivendo qualche playbook più complesso e parleremo degli handlers.