Ansible és una eina d'automatització IT que permet:
Avantatges:
Comparació amb scripts SSH:
# Script SSH tradicional
for servidor in web1 web2 web3; do
ssh $servidor "apt update && apt install nginx -y"
done
# Problema: No és idempotent, no gestiona errors bé, difícil de mantenir
# Amb Ansible
ansible webservers -m apt -a "name=nginx state=present"
# ✓ Idempotent
# ✓ Gestió d'errors
# ✓ Fàcil de llegir
# Debian/Ubuntu
sudo apt update
sudo apt install ansible -y
# Fedora/RHEL
sudo dnf install ansible -y
# macOS
brew install ansible
# Amb pip (qualsevol sistema)
pip3 install ansible
# Verificar instal·lació
ansible --version
Important: Ansible només s'instal·la al control node. Als managed nodes només cal SSH i Python.
Ansible usa SSH, així que cal tenir claus configurades:
# Generar clau (si no en tens)
ssh-keygen -t ed25519
# Copiar a cada servidor
ssh-copy-id usuari@servidor1
ssh-copy-id usuari@servidor2
L'inventory és un fitxer que defineix els servidors que Ansible gestionarà.
# /etc/ansible/hosts o ./hosts
# Hosts individuals
servidor1.exemple.cat
192.168.1.10
# Grups de hosts
[webservers]
web1.exemple.cat
web2.exemple.cat
web3.exemple.cat
[databases]
db1.exemple.cat
db2.exemple.cat
# Grups de grups
[producció:children]
webservers
databases
# Variables per host
[webservers]
web1.exemple.cat ansible_user=admin ansible_port=2222
web2.exemple.cat ansible_user=root
# Variables per grup
[webservers:vars]
ansible_user=deploy
http_port=80
# inventory.yml
all:
children:
webservers:
hosts:
web1.exemple.cat:
web2.exemple.cat:
web3.exemple.cat:
vars:
ansible_user: deploy
http_port: 80
databases:
hosts:
db1.exemple.cat:
db2.exemple.cat:
vars:
ansible_user: postgres
# Llistar tots els hosts
ansible all --list-hosts -i hosts
# Llistar hosts d'un grup
ansible webservers --list-hosts -i hosts
# Veure variables d'un host
ansible web1.exemple.cat -m debug -a "var=hostvars[inventory_hostname]" -i hosts
Els mòduls són les eines que Ansible usa per fer tasques. Hi ha centenars de mòduls.
ansible all -m ping -i hosts
ansible webservers -m shell -a "uptime" -i hosts
ansible all -m shell -a "df -h /" -i hosts
ansible all -m command -a "hostname" -i hosts
# Instal·lar paquet
ansible webservers -m apt -a "name=nginx state=present" -i hosts -b
# Actualitzar cache
ansible all -m apt -a "update_cache=yes" -i hosts -b
# Actualitzar tots els paquets
ansible all -m apt -a "upgrade=dist" -i hosts -b
ansible all -m dnf -a "name=httpd state=present" -i hosts -b
# Copiar fitxer local a remot
ansible webservers -m copy -a "src=/local/file.txt dest=/remote/file.txt" -i hosts
# Amb permisos específics
ansible webservers -m copy -a "src=config.conf dest=/etc/app/config.conf mode=0644 owner=root" -i hosts -b
# Crear directori
ansible all -m file -a "path=/opt/app state=directory mode=0755" -i hosts -b
# Eliminar fitxer
ansible all -m file -a "path=/tmp/old.log state=absent" -i hosts
# Iniciar servei
ansible webservers -m service -a "name=nginx state=started" -i hosts -b
# Reiniciar servei
ansible webservers -m service -a "name=nginx state=restarted" -i hosts -b
# Enable al boot
ansible webservers -m service -a "name=nginx enabled=yes" -i hosts -b
# Crear usuari
ansible all -m user -a "name=deploy state=present shell=/bin/bash" -i hosts -b
# Afegir a grup
ansible all -m user -a "name=deploy groups=sudo append=yes" -i hosts -b
# -i: Especificar inventory
ansible all -m ping -i hosts
# -b o --become: Executar com a root (sudo)
ansible all -m apt -a "name=nginx state=present" -i hosts -b
# --become-user: Executar com a un usuari específic
ansible all -m shell -a "whoami" -i hosts -b --become-user=postgres
# -u: Especificar usuari SSH
ansible all -m ping -i hosts -u admin
# -k o --ask-pass: Demanar contrasenya SSH
ansible all -m ping -i hosts -k
# -K o --ask-become-pass: Demanar contrasenya sudo
ansible all -m apt -a "name=nginx state=present" -i hosts -b -K
# -v, -vv, -vvv: Verbositat (debug)
ansible all -m ping -i hosts -v
Els playbooks són fitxers YAML que defineixen conjunts de tasques.
---
# playbook.yml
- name: Nom descriptiu del play
hosts: grup_de_hosts
become: yes # Executar com a root
vars:
# Variables locals
variable1: valor1
variable2: valor2
tasks:
- name: Descripció de la tasca
mòdul:
paràmetre1: valor1
paràmetre2: valor2
---
# nginx.yml
- name: Instal·lar i configurar nginx
hosts: webservers
become: yes
tasks:
- name: Actualitzar cache d'apt
apt:
update_cache: yes
- name: Instal·lar nginx
apt:
name: nginx
state: present
- name: Copiar fitxer de configuració
copy:
src: files/nginx.conf
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: '0644'
- name: Assegurar que nginx està iniciat
service:
name: nginx
state: started
enabled: yes
- name: Reiniciar nginx per aplicar canvis
service:
name: nginx
state: restarted
Executar el playbook:
ansible-playbook nginx.yml -i hosts
---
# deploy_web.yml
- name: Desplegar aplicació web
hosts: webservers
become: yes
vars:
app_dir: /var/www/html
app_user: www-data
tasks:
- name: Crear directori de l'aplicació
file:
path: "{{ app_dir }}"
state: directory
owner: "{{ app_user }}"
mode: '0755'
- name: Copiar fitxers de l'aplicació
copy:
src: "{{ item }}"
dest: "{{ app_dir }}/"
owner: "{{ app_user }}"
loop:
- files/index.html
- files/style.css
- files/script.js
- name: Copiar imatges
copy:
src: files/images/
dest: "{{ app_dir }}/images/"
owner: "{{ app_user }}"
---
- name: Exemple de variables
hosts: all
vars:
# Variables simples
nom_paquet: nginx
port: 80
# Llistes
paquets:
- git
- curl
- vim
# Diccionaris
usuari:
nom: deploy
grup: deploy
shell: /bin/bash
tasks:
- name: Instal·lar paquet
apt:
name: "{{ nom_paquet }}"
state: present
- name: Instal·lar múltiples paquets
apt:
name: "{{ item }}"
state: present
loop: "{{ paquets }}"
- name: Crear usuari
user:
name: "{{ usuari.nom }}"
group: "{{ usuari.grup }}"
shell: "{{ usuari.shell }}"
---
- name: Configurar servei
hosts: webservers
become: yes
tasks:
- name: Copiar configuració
copy:
src: files/app.conf
dest: /etc/app/app.conf
notify: Reiniciar app # Crida al handler si hi ha canvis
- name: Copiar certificat SSL
copy:
src: files/cert.pem
dest: /etc/ssl/cert.pem
notify: Reiniciar app
handlers:
- name: Reiniciar app
service:
name: app
state: restarted
Els handlers només s'executen:
---
- name: Tasques condicionals
hosts: all
tasks:
- name: Instal·lar nginx (només Ubuntu/Debian)
apt:
name: nginx
state: present
when: ansible_os_family == "Debian"
- name: Instal·lar httpd (només RedHat/CentOS)
yum:
name: httpd
state: present
when: ansible_os_family == "RedHat"
- name: Crear usuari si no existeix
user:
name: deploy
state: present
when: ansible_user_id != "deploy"
---
- name: Exemple de bucles
hosts: all
tasks:
- name: Crear múltiples usuaris
user:
name: "{{ item }}"
state: present
loop:
- user1
- user2
- user3
- name: Crear usuaris amb més dades
user:
name: "{{ item.name }}"
group: "{{ item.group }}"
shell: "{{ item.shell }}"
loop:
- { name: 'user1', group: 'users', shell: '/bin/bash' }
- { name: 'user2', group: 'admin', shell: '/bin/zsh' }
projecte_ansible/
├── ansible.cfg # Configuració d'Ansible
├── inventory/
│ ├── hosts # Inventory principal
│ ├── group_vars/ # Variables per grup
│ │ ├── all.yml
│ │ ├── webservers.yml
│ │ └── databases.yml
│ └── host_vars/ # Variables per host
│ ├── web1.yml
│ └── db1.yml
├── playbooks/
│ ├── site.yml # Playbook principal
│ ├── webservers.yml
│ └── databases.yml
├── roles/ # Roles (avançat)
├── files/ # Fitxers a copiar
└── templates/ # Plantilles Jinja2
[defaults]
inventory = ./inventory/hosts
remote_user = deploy
host_key_checking = False
retry_files_enabled = False
[privilege_escalation]
become = True
become_method = sudo
become_user = root
become_ask_pass = False
- name: Mostrar variables
hosts: all
tasks:
- name: Mostrar tots els facts
debug:
var: ansible_facts
- name: Mostrar variable específica
debug:
var: ansible_distribution
- name: Missatge personalitzat
debug:
msg: "El servidor és {{ inventory_hostname }}"
# Veure què faria sense fer-ho
ansible-playbook playbook.yml -i hosts --check
# Mostrar diferències
ansible-playbook playbook.yml -i hosts --check --diff
# Executar només tasques amb tag específic
ansible-playbook playbook.yml -i hosts --tags "config"
# Saltar tasques amb tag
ansible-playbook playbook.yml -i hosts --skip-tags "slow"
---
- name: Playbook amb tags
hosts: all
tasks:
- name: Instal·lar paquets
apt:
name: nginx
tags: install
- name: Configurar servei
copy:
src: config.conf
dest: /etc/nginx/
tags: config
name: descriptius--check abans de desplegaransible per comandes ad-hocansible-playbook per executar playbooks--check abans de desplegar