# Debian/Ubuntu
sudo apt install ansible -y
# Verificar
ansible --version
Necessitareu accés a almenys 2-3 servidors/VMs. Opcions:
Opció A: Contenidors Docker (més fàcil per proves locals)
# Crear xarxa
docker network create ansible-net
# Crear 3 contenidors SSH
for i in 1 2 3; do
docker run -d --name node$i \
--network ansible-net \
-p 222$i:22 \
rastasheep/ubuntu-sshd:18.04
done
# Obtenir IPs
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' node1
Opció B: Màquines virtuals (VirtualBox, QEMU, etc.)
Opció C: Servidors reals (si en teniu accés)
# Generar clau si no en tens
ssh-keygen -t ed25519 -f ~/.ssh/ansible_key
# Copiar a cada node (adapta segons el teu entorn)
ssh-copy-id -i ~/.ssh/ansible_key root@node1
ssh-copy-id -i ~/.ssh/ansible_key root@node2
ssh-copy-id -i ~/.ssh/ansible_key root@node3
# Provar connexió
ssh -i ~/.ssh/ansible_key root@node1
Crea un fitxer inventory/hosts:
[all:vars]
ansible_user=root
ansible_ssh_private_key_file=~/.ssh/ansible_key
[webservers]
node1 ansible_host=192.168.1.10
node2 ansible_host=192.168.1.11
[databases]
node3 ansible_host=192.168.1.12
Adapta les IPs als teus nodes!
# Comprovar tots els hosts
ansible all -m ping -i inventory/hosts
# Comprovar només webservers
ansible webservers -m ping -i inventory/hosts
# Obtenir informació del sistema
ansible all -m setup -i inventory/hosts | grep ansible_distribution
Crea playbooks/install_packages.yml:
---
- name: Instal·lar paquets bàsics a tots els servidors
hosts: all
become: yes
tasks:
- name: Actualitzar cache d'apt
apt:
update_cache: yes
cache_valid_time: 3600
- name: Instal·lar paquets bàsics
apt:
name:
- vim
- git
- curl
- htop
- net-tools
state: present
- name: Mostrar missatge de confirmació
debug:
msg: "Paquets instal·lats correctament a {{ inventory_hostname }}"
- name: Instal·lar nginx als webservers
hosts: webservers
become: yes
tasks:
- name: Instal·lar nginx
apt:
name: nginx
state: present
- name: Assegurar que nginx està iniciat
service:
name: nginx
state: started
enabled: yes
- name: Verificar que nginx funciona
command: curl -s http://localhost
register: nginx_output
changed_when: false
- name: Mostrar resultat
debug:
msg: "Nginx funcionant: {{ 'OK' if 'nginx' in nginx_output.stdout else 'ERROR' }}"
Executa el playbook:
ansible-playbook playbooks/install_packages.yml -i inventory/hosts
Verifica que s'ha instal·lat correctament:
ansible webservers -m command -a "nginx -v" -i inventory/hosts
ansible all -m command -a "git --version" -i inventory/hosts
Executa el playbook una segona vegada. Què passa? Per què?
Modifica el playbook per afegir més paquets (per exemple: python3-pip, tree, wget)
PLAY [Instal·lar paquets bàsics a tots els servidors] *************************
TASK [Gathering Facts] *********************************************************
ok: [node1]
ok: [node2]
ok: [node3]
TASK [Actualitzar cache d'apt] *************************************************
changed: [node1]
changed: [node2]
changed: [node3]
TASK [Instal·lar paquets bàsics] ***********************************************
changed: [node1]
changed: [node2]
changed: [node3]
PLAY [Instal·lar nginx als webservers] *****************************************
TASK [Instal·lar nginx] ********************************************************
changed: [node1]
changed: [node2]
TASK [Assegurar que nginx està iniciat] ***************************************
ok: [node1]
ok: [node2]
PLAY RECAP *********************************************************************
node1 : ok=6 changed=3 unreachable=0 failed=0
node2 : ok=6 changed=3 unreachable=0 failed=0
node3 : ok=3 changed=2 unreachable=0 failed=0
Crea un playbook que desplega una aplicació web simple amb configuració personalitzada.
mkdir -p files/web
Crea files/web/index.html:
<!DOCTYPE html>
<html>
<head>
<title>{{ server_name }}</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Benvingut a {{ server_name }}</h1>
<p>Servidor: {{ inventory_hostname }}</p>
<p>Versió: {{ app_version }}</p>
</body>
</html>
Crea files/web/style.css:
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 50px auto;
padding: 20px;
background: #f0f0f0;
}
h1 {
color: #333;
border-bottom: 2px solid #007bff;
}
Crea files/nginx_site.conf:
server {
listen 80;
server_name _;
root /var/www/myapp;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
Nota: Ansible usa Jinja2 per templates. Crea templates/index.html.j2 (versió amb variables):
<!DOCTYPE html>
<html>
<head>
<title>{{ server_name }}</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Benvingut a {{ server_name }}</h1>
<p>Servidor: {{ inventory_hostname }}</p>
<p>IP: {{ ansible_default_ipv4.address }}</p>
<p>Sistema: {{ ansible_distribution }} {{ ansible_distribution_version }}</p>
<p>Versió app: {{ app_version }}</p>
<p>Desplegat el: {{ ansible_date_time.date }} a les {{ ansible_date_time.time }}</p>
</body>
</html>
Crea playbooks/deploy_web.yml:
---
- name: Desplegar aplicació web
hosts: webservers
become: yes
vars:
app_dir: /var/www/myapp
server_name: "Mon Servidor Web"
app_version: "1.0.0"
tasks:
- name: Crear directori de l'aplicació
file:
path: "{{ app_dir }}"
state: directory
owner: www-data
group: www-data
mode: '0755'
- name: Desplegar index.html amb template
template:
src: ../templates/index.html.j2
dest: "{{ app_dir }}/index.html"
owner: www-data
group: www-data
mode: '0644'
notify: Reiniciar nginx
- name: Copiar CSS
copy:
src: ../files/web/style.css
dest: "{{ app_dir }}/style.css"
owner: www-data
group: www-data
mode: '0644'
- name: Configurar site nginx
copy:
src: ../files/nginx_site.conf
dest: /etc/nginx/sites-available/myapp
owner: root
group: root
mode: '0644'
notify: Reiniciar nginx
- name: Activar site
file:
src: /etc/nginx/sites-available/myapp
dest: /etc/nginx/sites-enabled/myapp
state: link
notify: Reiniciar nginx
- name: Desactivar site per defecte
file:
path: /etc/nginx/sites-enabled/default
state: absent
notify: Reiniciar nginx
- name: Verificar configuració nginx
command: nginx -t
register: nginx_test
changed_when: false
- name: Mostrar resultat verificació
debug:
var: nginx_test.stderr_lines
handlers:
- name: Reiniciar nginx
service:
name: nginx
state: restarted
Crea l'estructura de directoris i fitxers
Executa el playbook:
ansible-playbook playbooks/deploy_web.yml -i inventory/hosts
Verifica que l'aplicació funciona:
ansible webservers -m command -a "curl -s http://localhost" -i inventory/hosts
Modifica app_version a "2.0.0" i torna a desplegar
Comprova que els handlers només es criden quan hi ha canvis
Afegeix una tasca que:
info.json amb informació del servidortemplate amb una plantilla Jinja2Crea un playbook que recull informació de tots els servidors i genera un informe.
playbooks/audit.yml---
- name: Audit de servidors
hosts: all
become: yes
tasks:
- name: Recollir informació del sistema
setup:
gather_subset:
- 'all'
- name: Obtenir serveis actius
service_facts:
- name: Llistar paquets instal·lats
package_facts:
manager: apt
- name: Comprovar últim login
command: lastlog -u root
register: last_login
changed_when: false
- name: Verificar espai en disc
command: df -h /
register: disc_info
changed_when: false
- name: Generar informe local
delegate_to: localhost
become: no
copy:
content: |
====================================
INFORME D'AUDIT: {{ inventory_hostname }}
Data: {{ ansible_date_time.iso8601 }}
====================================
SISTEMA:
- Distribució: {{ ansible_distribution }} {{ ansible_distribution_version }}
- Kernel: {{ ansible_kernel }}
- Arquitectura: {{ ansible_architecture }}
- Hostname: {{ ansible_hostname }}
- FQDN: {{ ansible_fqdn }}
XARXA:
- IP principal: {{ ansible_default_ipv4.address }}
- Gateway: {{ ansible_default_ipv4.gateway }}
- DNS: {{ ansible_dns.nameservers | join(', ') }}
RECURSOS:
- CPUs: {{ ansible_processor_vcpus }}
- Memòria total: {{ ansible_memtotal_mb }} MB
- Memòria lliure: {{ ansible_memfree_mb }} MB
- Swap total: {{ ansible_swaptotal_mb }} MB
DISC:
{{ disc_info.stdout }}
SERVEIS ACTIUS:
{% for service in ansible_facts.services.keys() | sort %}
{% if ansible_facts.services[service].state == "running" %}
- {{ service }}: {{ ansible_facts.services[service].state }}
{% endif %}
{% endfor %}
ÚLTIM LOGIN ROOT:
{{ last_login.stdout }}
dest: "./reports/audit_{{ inventory_hostname }}_{{ ansible_date_time.date }}.txt"
run_once: false
- name: Generar resum consolidat
hosts: localhost
gather_facts: no
tasks:
- name: Crear resum
shell: |
echo "=====================================" > reports/resum.txt
echo "RESUM D'AUDIT - $(date)" >> reports/resum.txt
echo "=====================================" >> reports/resum.txt
echo "" >> reports/resum.txt
echo "Total servidors auditats: {{ groups['all'] | length }}" >> reports/resum.txt
echo "" >> reports/resum.txt
echo "Informes individuals generats:" >> reports/resum.txt
ls -1 reports/audit_* >> reports/resum.txt
args:
creates: reports/resum.txt
Crea el directori reports/
Executa el playbook:
ansible-playbook playbooks/audit.yml -i inventory/hosts
Revisa els informes generats:
cat reports/resum.txt
cat reports/audit_node1_*.txt
Modifica el playbook per afegir més informació:
reports/
├── audit_node1_2024-01-08.txt
├── audit_node2_2024-01-08.txt
├── audit_node3_2024-01-08.txt
└── resum.txt
Crea un playbook que actualitza tots els servidors de forma segura:
---
- name: Actualització segura de servidors
hosts: all
become: yes
serial: 1 # Actualitzar un servidor cada vegada
tasks:
- name: Backup de llista de paquets
shell: dpkg --get-selections > /tmp/packages_backup_{{ ansible_date_time.epoch }}.txt
changed_when: false
- name: Actualitzar cache
apt:
update_cache: yes
- name: Comprovar paquets actualitzables
command: apt list --upgradable
register: upgradable_packages
changed_when: false
- name: Actualitzar tots els paquets
apt:
upgrade: dist
register: upgrade_result
- name: Comprovar si cal reiniciar
stat:
path: /var/run/reboot-required
register: reboot_required
- name: Generar informe
# ... implementar