Ansible

Capitolo 1 – Cos'è Ansible

1.1 Definizione

Ansible è uno strumento di automazione IT open source utilizzato per:

È sviluppato da Red Hat ed è oggi uno degli strumenti più utilizzati in ambito sistemistico e DevOps.

A differenza di altre soluzioni (come Puppet o Chef), Ansible è agentless: non richiede l'installazione di alcun agente sui nodi gestiti.


1.2 A cosa serve in ambito Sysadmin

In un contesto sistemistico, Ansible permette di:

Esempio pratico:

Senza Ansible:

Con Ansible:


1.3 Architettura di base

Ansible utilizza un'architettura molto semplice.

Control Node

Macchina su cui è installato Ansible e da cui partono i comandi.

Managed Nodes

Server gestiti da Ansible tramite SSH.

Inventory

File che definisce l'elenco dei server da gestire.

Playbook

File YAML che descrive lo stato desiderato dei sistemi.


1.4 Come funziona

Il flusso operativo è il seguente:

  1. Ansible legge l'inventory
  2. Si connette ai nodi via SSH
  3. Esegue i moduli richiesti
  4. Riporta l'esito dell'operazione

Ansible lavora in modalità dichiarativa:
non si descrive "come fare", ma "quale deve essere lo stato finale".

Esempio concettuale:

Questo comportamento si chiama idempotenza.


1.5 Perché è scelto in ambienti professionali

Ansible è diffuso in ambienti enterprise per diversi motivi:

È utilizzato sia per piccole infrastrutture che per ambienti complessi multi-tier.


1.6 Casi d’uso tipici


1.7 Quando NON usare Ansible

Ansible non è pensato per:

È uno strumento di automazione e gestione configurazione, non un sistema di controllo runtime continuo.


Conclusione

Ansible è uno strumento centrale nel toolkit di un sistemista moderno.

Permette di trasformare operazioni manuali in procedure automatizzate, ripetibili e versionabili, riducendo errori e aumentando la coerenza dell'infrastruttura.

Nel prossimo capitolo entreremo nella configurazione iniziale operativa dopo l’installazione.

Capitolo 2 – Architettura e Componenti di Ansible

Dopo aver compreso cos’è Ansible, è fondamentale capire come è strutturato e quali sono i suoi componenti principali.

Una corretta comprensione dell’architettura è essenziale per utilizzarlo in modo professionale in ambienti server.


2.1 Modello Architetturale

Ansible utilizza un modello push-based.

Questo significa che:

Questo approccio riduce complessità, consumo risorse e superficie di attacco.


2.2 Control Node

Il Control Node è la macchina su cui è installato Ansible.

Caratteristiche:

Requisiti:

In ambienti enterprise il Control Node può essere:


2.3 Managed Nodes

I Managed Nodes sono i server che vengono configurati da Ansible.

Requisiti minimi:

Importante:
Non è richiesto alcun agente Ansible installato sul nodo remoto.

Questo è uno dei principali vantaggi rispetto ad altri strumenti di configuration management.


2.4 Inventory

L’Inventory è il file che definisce quali server devono essere gestiti.

Può essere:

Esempio concettuale:

L’inventory è il punto di partenza di qualsiasi esecuzione.


2.5 Moduli

I Moduli sono le unità operative di Ansible.

Sono piccoli programmi che:

Quando eseguiamo un comando Ansible:

  1. Il modulo viene copiato temporaneamente sul nodo remoto
  2. Viene eseguito
  3. Restituisce un output JSON
  4. Viene rimosso

Questo processo è trasparente per l’amministratore.


2.6 Playbook

I Playbook sono file YAML che descrivono lo stato desiderato dell’infrastruttura.

Definiscono:

Un playbook può:

Rappresentano il cuore dell’automazione con Ansible.


2.7 Idempotenza

Concetto fondamentale in ambito sistemistico.

Un’operazione è idempotente quando:

Esempio:

Questo garantisce:


2.8 Flusso di Esecuzione

Quando si lancia un playbook:

  1. Ansible carica il file di configurazione
  2. Legge l’inventory
  3. Stabilisce connessioni SSH
  4. Esegue i task in ordine
  5. Riporta lo stato finale (ok, changed, failed)

L’output fornisce:


Conclusione

Ansible si basa su un’architettura semplice ma estremamente potente:

Comprendere questi elementi è fondamentale prima di passare alla configurazione operativa.

Nel prossimo capitolo entreremo nella configurazione iniziale dell’ambiente di lavoro: inventory, ansible.cfg e struttura progetto.

Capitolo 3 – Configurazione Iniziale dell’Ambiente di Lavoro

Dopo aver compreso architettura e componenti, il passo successivo è impostare correttamente l’ambiente operativo. In ambito sysadmin è fondamentale non lavorare in modo disordinato.
Una struttura chiara permette scalabilità, manutenzione e integrazione con Git.


3.1 Non lavorare in /etc/ansible

Ansible può utilizzare:

Tuttavia, in ambienti professionali è sconsigliato lavorare direttamente lì.

Motivi:

Best practice: creare una directory progetto dedicata.


3.2 Creazione Struttura Base Progetto

Esempio struttura iniziale:

mkdir -p ~/ansible/{inventory,playbooks,roles,group_vars,host_vars}
cd ~/ansible

Struttura consigliata:

ansible/
├── ansible.cfg
├── inventory/
│   ├── production
│   ├── staging
│   └── dev
├── playbooks/
├── roles/
├── group_vars/
└── host_vars/

Descrizione:

Questa struttura è scalabile e adatta a infrastrutture reali.


3.3 Creazione del File ansible.cfg Locale

Creare un file ansible.cfg nella root del progetto:

[defaults]
inventory = ./inventory/production
remote_user = ansible
host_key_checking = False
retry_files_enabled = False
roles_path = ./roles
forks = 10
timeout = 30

[privilege_escalation]
become = True
become_method = sudo
become_ask_pass = False

Spiegazione Parametri Principali


3.4 Ordine di Precedenza del File di Configurazione

Ansible legge il file di configurazione in questo ordine:

  1. Variabile ambiente ANSIBLE_CONFIG
  2. ansible.cfg nella directory corrente
  3. ~/.ansible.cfg
  4. /etc/ansible/ansible.cfg

Questo significa che il file locale nel progetto ha priorità rispetto a quello globale.

Verifica configurazione attiva:

ansible-config view

3.5 Configurazione SSH Corretta

Prerequisito fondamentale: accesso SSH senza password.

Generazione chiave (se non esiste):

ssh-keygen -t ed25519

Copia chiave sui nodi remoti:

ssh-copy-id ansible@server

Test connessione:

ssh ansible@server

Best practice:


3.6 Verifica Connessione con Ansible

Prima di scrivere playbook, verificare la connettività.

Esempio:

ansible all -m ping

Output atteso:

Se compare errore Python, verificare presenza di python3 sul nodo remoto.


3.7 Preparazione per Ambienti Multipli

Separare ambienti evita errori critici.

Esempio:

inventory/
├── production
├── staging
└── dev

Esecuzione su staging:

ansible-playbook -i inventory/staging playbooks/site.yml

Non mescolare mai produzione e ambienti di test nello stesso inventory.


Conclusione

Una corretta configurazione iniziale è fondamentale per:

Nel prossimo capitolo entreremo nel dettaglio dell’Inventory: sintassi, gruppi, variabili e struttura professionale.

Capitolo 4 – Inventory: Struttura e Gestione Professionale

L’inventory è il punto di partenza di qualsiasi operazione con Ansible.

Definisce:

Una gestione corretta dell’inventory è fondamentale in ambienti sysadmin.


4.1 Inventory Statico (Formato INI)

È il formato più semplice e immediato.

Esempio file inventory/production:

[web]
web01 ansible_host=192.168.10.10
web02 ansible_host=192.168.10.11

[db]
db01 ansible_host=192.168.10.20

[all:vars]
ansible_user=ansible
ansible_python_interpreter=/usr/bin/python3

Spiegazione

Test di connettività:

ansible all -m ping

4.2 Parametri Host Specifici

È possibile definire parametri direttamente sull’host:

web01 ansible_host=192.168.10.10 ansible_port=2222 ansible_user=deploy

Parametri comuni:

Questo permette di gestire ambienti eterogenei.


4.3 Inventory in YAML

Alternativa più leggibile in ambienti complessi.

Esempio:

all:
  vars:
    ansible_user: ansible
    ansible_python_interpreter: /usr/bin/python3
  children:
    web:
      hosts:
        web01:
          ansible_host: 192.168.10.10
        web02:
          ansible_host: 192.168.10.11
    db:
      hosts:
        db01:
          ansible_host: 192.168.10.20

Vantaggi:


4.4 Gruppi e Sottogruppi

È possibile creare gruppi annidati.

Esempio:

[web]
web01
web02

[frontend]
web01

[backend]
web02

[production:children]
web
db

Questo permette di:

Esempio esecuzione su gruppo specifico:

ansible web -m command -a "uptime"

4.5 File group_vars e host_vars

Separare le variabili dall’inventory è una best practice.

Struttura:

group_vars/
├── web.yml
├── db.yml

host_vars/
├── web01.yml

Esempio group_vars/web.yml:

http_port: 80
max_clients: 200

Esempio host_vars/web01.yml:

http_port: 8080

Regola importante:

Le variabili host specifiche hanno priorità su quelle di gruppo.


4.6 Separazione Ambienti

Non utilizzare mai un unico inventory per tutto.

Struttura consigliata:

inventory/
├── production
├── staging
└── dev

Esecuzione su ambiente specifico:

ansible-playbook -i inventory/staging playbooks/site.yml

Questo evita errori critici su produzione.


4.7 Best Practice Sysadmin


4.8 Verifica Inventory

Comandi utili:

Visualizzare host:

ansible-inventory -i inventory/production --list

Visualizzare struttura grafica:

ansible-inventory -i inventory/production --graph

Questi strumenti aiutano nel troubleshooting.


Conclusione

L’inventory non è solo un elenco di server.
È la rappresentazione logica della tua infrastruttura.

Una progettazione corretta permette:

Nel prossimo capitolo entreremo nei Comandi Ad-Hoc e nell’operatività quotidiana da sysadmin.

Capitolo 5 – Comandi Ad-Hoc e Operatività Quotidiana

I comandi ad-hoc permettono di eseguire operazioni rapide sui nodi gestiti senza scrivere un playbook.

Sono utili per:

Non sostituiscono i playbook in ambienti strutturati, ma sono uno strumento operativo fondamentale per un sysadmin.


5.1 Sintassi Base

Struttura generale:

ansible <gruppo_host> -m <modulo> -a "<argomenti>"

Esempio:

ansible all -m ping

Componenti:


5.2 Verifica Connettività

Test base su tutti i server:

ansible all -m ping

Se tutto è configurato correttamente, l’output sarà:


5.3 Eseguire Comandi Remoti

Modulo command

Esegue un comando senza passare dalla shell.

ansible all -m command -a "uptime"

Caratteristiche:

È più sicuro rispetto a shell.


Modulo shell

Usa la shell del sistema remoto.

ansible all -m shell -a "df -h | grep /dev/sda1"

Usare solo quando necessario.

Best practice: preferire sempre moduli nativi.


5.4 Gestione Pacchetti

Installare un pacchetto su gruppo web:

ansible web -m apt -a "name=nginx state=present update_cache=yes"

Rimuovere un pacchetto:

ansible web -m apt -a "name=nginx state=absent"

Versione generica (cross-distribution):

ansible all -m package -a "name=htop state=present"

5.5 Gestione Servizi

Avviare un servizio:

ansible web -m service -a "name=nginx state=started"

Riavviare:

ansible web -m service -a "name=nginx state=restarted"

Abilitare all’avvio:

ansible web -m service -a "name=nginx enabled=yes"

5.6 Gestione Utenti

Creare un utente:

ansible all -m user -a "name=deploy shell=/bin/bash groups=sudo append=yes"

Rimuovere un utente:

ansible all -m user -a "name=deploy state=absent remove=yes"

5.7 Copiare File

Copiare file locale su remoto:

ansible web -m copy -a "src=/tmp/test.txt dest=/tmp/test.txt owner=root group=root mode=0644"

5.8 Uso di Privilege Escalation

Se necessario eseguire come root:

ansible all -m apt -a "name=vim state=present" --become

Se become è già abilitato in ansible.cfg, non serve specificarlo.


5.9 Limitare l’Esecuzione

Eseguire solo su un host specifico:

ansible web01 -m command -a "hostname"

Limitare tramite opzione --limit:

ansible all -m ping --limit web

5.10 Esecuzione Parallela e Fork

Ansible esegue operazioni in parallelo.

Numero default: 5 fork.

Modificabile:

ansible all -m ping -f 20

Oppure in ansible.cfg:

forks = 20

5.11 Output e Debug

Aumentare verbosità:

ansible all -m ping -vvv

Livelli disponibili:

Utile per troubleshooting SSH o problemi di autenticazione.


5.12 Quando Usare i Comandi Ad-Hoc

Utilizzare quando:

Non utilizzare quando:

In questi casi è corretto scrivere un playbook.


Conclusione

I comandi ad-hoc sono uno strumento operativo quotidiano per il sysadmin.

Permettono interventi rapidi e controllati, ma non sostituiscono l’automazione strutturata.

Nel prossimo capitolo entreremo nel cuore di Ansible: i Playbook.

Capitolo 6 – Primo Playbook Reale: Setup Base Server

Dopo aver visto i comandi ad-hoc, è il momento di passare ai playbook, il cuore dell’automazione con Ansible.

Un playbook permette di definire lo stato desiderato dei server in modo dichiarativo e ripetibile.


6.1 Struttura di un Playbook

Un playbook è un file YAML composto da:

Esempio concettuale:

- name: Configurazione base server
  hosts: all
  become: true
  tasks:
    - name: Aggiornare cache pacchetti
      apt:
        update_cache: yes

6.2 Playbook Base

File: playbooks/base.yml

- name: Configurazione base server
  hosts: all
  become: true

  tasks:
    - name: Aggiornamento cache apt
      apt:
        update_cache: yes
      when: ansible_os_family == "Debian"

    - name: Installazione pacchetti base
      package:
        name:
          - vim
          - curl
          - htop
          - git
        state: present

    - name: Creazione utente deploy
      user:
        name: deploy
        groups: sudo
        append: yes
        shell: /bin/bash

Spiegazione


6.3 Esecuzione del Playbook

Esecuzione base:

ansible-playbook playbooks/base.yml

Modalità di check (simulazione senza modifiche):

ansible-playbook playbooks/base.yml --check

Modalità verbose:

ansible-playbook playbooks/base.yml -vvv

6.4 Best Practice per Playbook


6.5 Prossimi Passi

Dopo aver creato e testato il primo playbook:


Conclusione

Il primo playbook rappresenta il primo passo concreto verso l’automazione.

Da questo momento è possibile standardizzare setup, gestire pacchetti, utenti e configurazioni in modo ripetibile e sicuro.

Nei capitoli successivi approfondiremo la gestione di ruoli, variabili avanzate e segreti, e la strutturazione professionale di progetti Ansible.

Capitolo 7 – Ruoli, Variabili e Gestione Segreti

Dopo aver imparato i playbook base, è fondamentale organizzare i progetti in modo modulare e sicuro.


7.1 Introduzione ai Ruoli

I ruoli permettono di raggruppare tasks, file, template e variabili in moduli riutilizzabili.

Struttura tipica di un ruolo nginx:

roles/
└── nginx/
    ├── tasks/
    │   └── main.yml
    ├── templates/
    │   └── nginx.conf.j2
    ├── files/
    ├── vars/
    │   └── main.yml
    ├── defaults/
    │   └── main.yml
    └── handlers/
        └── main.yml

7.2 Creazione di un Ruolo

Esempio:

ansible-galaxy init nginx

Questo comando genera automaticamente la struttura del ruolo.


7.3 Utilizzo dei Ruoli in un Playbook

Esempio playbooks/web.yml:

- name: Configurazione Web Server
  hosts: web
  become: true
  roles:
    - nginx

Il ruolo viene eseguito con tutte le sue tasks, handlers, template e variabili.


7.4 Variabili

Le variabili possono essere definite in diversi livelli di precedenza:

  1. Variabili host specifiche (host_vars/host1.yml)
  2. Variabili di gruppo (group_vars/web.yml)
  3. Variabili definite nel ruolo (vars/main.yml)
  4. Variabili di default del ruolo (defaults/main.yml)
  5. Variabili inline nel playbook

Esempio group_vars/web.yml:

http_port: 80
max_clients: 200

7.5 Gestione Segreti con Ansible Vault

Ansible Vault permette di cifrare variabili sensibili come password o chiavi.

Creazione file criptato:

ansible-vault create group_vars/web/secrets.yml

Esempio contenuto:

db_password: "SuperSegreta123"

Esecuzione playbook con Vault:

ansible-playbook playbooks/web.yml --ask-vault-pass

Modifica file criptato:

ansible-vault edit group_vars/web/secrets.yml

7.6 Best Practice Ruoli e Variabili


7.7 Conclusione

I ruoli, le variabili e la gestione dei segreti sono elementi fondamentali per strutturare progetti Ansible professionali.

Permettono:

Nei prossimi capitoli si può approfondire:

Capitolo 8 – Deploy Applicativo e Template Jinja2

Dopo aver appreso ruoli, variabili e gestione dei segreti, il passo successivo è imparare a deployare applicazioni in modo automatizzato e a utilizzare template Jinja2 per configurazioni dinamiche.


8.1 Cos’è un Template Jinja2

I template Jinja2 permettono di creare file di configurazione dinamici.

Caratteristiche principali:

Esempio minimo di template nginx.conf.j2:

server {
    listen {{ http_port }};
    server_name {{ server_name }};

    root {{ web_root }};
    index index.html;
}

8.2 Creazione di un Template per il Web Server

Esempio ruolo roles/nginx/templates/nginx.conf.j2:

user www-data;
worker_processes auto;

pid /run/nginx.pid;

events {
    worker_connections 768;
}

http {
    server {
        listen {{ http_port }};
        server_name {{ server_name }};
        root {{ web_root }};
        index index.html index.htm;

        location / {
            try_files $uri $uri/ =404;
        }
    }
}

Variabili tipiche da definire in group_vars/web.yml:

http_port: 80
server_name: example.com
web_root: /var/www/html

8.3 Copiare Template con il Modulo template

Playbook esempio: playbooks/deploy_web.yml

- name: Deploy Web Server
  hosts: web
  become: true

  roles:
    - nginx

  tasks:
    - name: Deploy configurazione nginx
      template:
        src: nginx.conf.j2
        dest: /etc/nginx/sites-available/default
        owner: root
        group: root
        mode: '0644'

    - name: Riavvia nginx se configurazione cambiata
      service:
        name: nginx
        state: restarted
      when: ansible_os_family == "Debian"

8.4 Gestione Deploy Applicativo Completo

Oltre al web server, un deploy tipico include:

Esempio snippet per copia codice:

- name: Clona repository applicativo
  git:
    repo: 'https://github.com/tuo-progetto/app.git'
    dest: /var/www/html
    version: main

8.5 Gestione Segreti nel Deploy

Variabili sensibili (API key, password DB) mai hardcodate.

Esempio group_vars/web/secrets.yml cifrato con Vault:

db_password: "SuperSegreta123"
api_key: "XYZ987654321"

Utilizzo nel template:

DB_PASSWORD={{ db_password }}
API_KEY={{ api_key }}

Esecuzione playbook con Vault:

ansible-playbook playbooks/deploy_web.yml --ask-vault-pass

8.6 Best Practice per Deploy


8.7 Conclusione

L’utilizzo di template Jinja2 e playbook modulare permette di:

Nei prossimi capitoli si può approfondire:

Capitolo 9 – Hardening e Sicurezza dei Server

Dopo aver imparato a deployare applicazioni, è fondamentale proteggere i server.

L’hardening consiste nell’applicare configurazioni e best practice per ridurre la superficie di attacco e aumentare la sicurezza.

Ansible è uno strumento ideale per automatizzare queste procedure.


9.1 Aggiornamenti di Sicurezza

Eseguire regolarmente aggiornamenti di sicurezza è fondamentale.

Esempio playbook:

- name: Aggiornamenti di sicurezza
  hosts: all
  become: true
  tasks:
    - name: Aggiornamento pacchetti Debian
      apt:
        upgrade: dist
      when: ansible_os_family == "Debian"

    - name: Aggiornamento pacchetti RedHat
      yum:
        name: "*"
        state: latest
      when: ansible_os_family == "RedHat"

9.2 Gestione Utenti e SSH

Esempio task per SSH:

- name: Disabilita root login SSH
  lineinfile:
    path: /etc/ssh/sshd_config
    regexp: '^PermitRootLogin'
    line: 'PermitRootLogin no'
  notify: Restart ssh

- name: Imposta chiavi SSH per utente deploy
  authorized_key:
    user: deploy
    state: present
    key: "{{ lookup('file', '~/.ssh/id_ed25519.pub') }}"

Handler per restart SSH:

- name: Restart ssh
  service:
    name: ssh
    state: restarted

9.3 Firewall e Accesso

Abilitare firewall con regole base:

- name: Configura UFW
  ufw:
    state: enabled
    rule: allow
    port: "{{ item }}"
  loop:
    - 22
    - 80
    - 443

9.4 Rimozione Pacchetti Non Necessari

Ridurre il rischio rimuovendo software inutile:

- name: Rimuovi pacchetti non necessari
  package:
    name: "{{ item }}"
    state: absent
  loop:
    - telnet
    - ftp
    - rsh-client

9.5 Logging e Audit

Abilitare logging e audit per monitorare accessi:

- name: Installazione auditd
  package:
    name: auditd
    state: present

- name: Avvia auditd
  service:
    name: auditd
    state: started
    enabled: yes

9.6 Sicurezza dei File di Configurazione

Esempio:

- name: Imposta permessi su segreti
  file:
    path: /etc/app/secrets.yml
    owner: root
    group: root
    mode: '0600'

9.7 Best Practice Hardening


9.8 Conclusione

Applicare hardening con Ansible permette di:

Nei prossimi capitoli si può approfondire:

Capitolo 10 – Logging, Monitoraggio e Troubleshooting

La gestione dei server non si limita a deploy e configurazione: è fondamentale monitorare lo stato e poter diagnosticare problemi rapidamente.

Ansible offre strumenti integrati per log e debug, ma è utile combinarli con best practice sysadmin.


10.1 Verbosità e Output

Per ottenere informazioni dettagliate durante l’esecuzione:

ansible-playbook playbooks/site.yml -v       # livello base
ansible-playbook playbooks/site.yml -vv      # più dettagli
ansible-playbook playbooks/site.yml -vvv     # debug SSH e task
ansible-playbook playbooks/site.yml -vvvv    # dettagli estremi (output completo)

10.2 Modulo Debug

Il modulo debug è fondamentale per verificare variabili o output intermedi.

Esempio:

- name: Mostra valore di una variabile
  debug:
    var: http_port

- name: Mostra messaggio personalizzato
  debug:
    msg: "Deploy completato su {{ inventory_hostname }}"

10.3 Check Mode

Permette di simulare l’esecuzione senza modificare i server.

ansible-playbook playbooks/base.yml --check

Utile per:


10.4 Test di Syntax

Prima di eseguire un playbook, controllarne la sintassi:

ansible-playbook playbooks/base.yml --syntax-check

Permette di:


10.5 Registrare Output

È possibile salvare l’output di un task in una variabile per uso successivo:

- name: Controlla spazio disco
  command: df -h /var
  register: disco

- name: Mostra spazio disco
  debug:
    var: disco.stdout

10.6 Gestione Errori

Esempio:

- name: Esegue comando con retry
  command: /usr/bin/check_service
  register: result
  retries: 3
  delay: 10
  until: result.rc == 0

10.7 Log Centralizzato

Per infrastrutture grandi, utile salvare output dei playbook:

ansible-playbook playbooks/site.yml | tee /var/log/ansible/site.log

10.8 Best Practice Troubleshooting


10.9 Conclusione

Un corretto approccio a logging e troubleshooting permette di: