Linux / Systèmes

📚 Scripting Bash Ansible Python PowerShell Automatisation

Bash, Ansible, Python Netmiko, cron — automatiser les tâches répétitives et gérer l'infrastructure as code.

BashAnsiblePython NetmikoCronPowerShellTerraform

Bash — Template de script robuste

Toujours commencer par set -euo pipefail : arrête le script sur erreur (-e), traite les variables non définies comme des erreurs (-u), et propage les erreurs dans les pipes (-o pipefail).

template.sh
#!/bin/bash
# Bonnes pratiques : arrêt sur erreur, var non définie, pipe
set -euo pipefail

# Variables globales
SCRIPT_DIR=$(cd "$(dirname "${{BASH_SOURCE[0]}}")" && pwd)
LOG_FILE="/var/log/mon-script.log"
DATE=$(date +"%Y-%m-%d %H:%M:%S")

# Fonction de log avec horodatage
log() {{
  echo "[$DATE] $*" | tee -a "$LOG_FILE"
}}

log_err() {{
  echo "[$DATE] ERROR: $*" | tee -a "$LOG_FILE" >&2
}}

# Vérification des privilèges root
[[ $EUID -ne 0 ]] && {{ log_err "Ce script doit être exécuté en root"; exit 1; }}

# Trap pour nettoyer en cas d'erreur
trap 'log_err "Erreur ligne $LINENO — code $?"' ERR

log "INFO: Démarrage du script"

# Votre logique ici

log "INFO: Script terminé avec succès"

Bash — Scripts utiles

backup-rsync.sh
#!/bin/bash
set -euo pipefail
SRC="/etc /var/www /home"
LOCAL="/backup/local"
REMOTE_HOST="backup-srv"
REMOTE_PATH="/backup/remote"
DATE=$(date +%Y%m%d)

# Copie locale incrémentale avec hardlinks
rsync -az --link-dest="$LOCAL/latest" $SRC "$LOCAL/$DATE/"
ln -snf "$LOCAL/$DATE" "$LOCAL/latest"

# Sync vers serveur distant via SSH
rsync -az -e "ssh -i /root/.ssh/backup_key" "$LOCAL/$DATE/" "$REMOTE_HOST:$REMOTE_PATH/$DATE/"

# Purger les sauvegardes de plus de 30 jours
find "$LOCAL" -maxdepth 1 -name "202*" -mtime +30 -exec rm -rf {{}} \;

echo "Sauvegarde $DATE terminée."
monitoring-check.sh
#!/bin/bash
# Vérification quotidienne système
THRESHOLD_CPU=80
THRESHOLD_DISK=90
ALERT_EMAIL="admin@entreprise.local"

# CPU
CPU=$(top -bn1 | grep "Cpu(s)" | awk '{{print int($2)}}')
[[ $CPU -gt $THRESHOLD_CPU ]] && echo "ALERTE CPU: $CPU%" | mail -s "Alerte CPU $(hostname)" $ALERT_EMAIL

# Disque
df -h | awk 'NR>1 {{gsub(/%/,""); if ($5 > 90) print "ALERTE disque "$6": "$5"%"}}' | \
  while read line; do echo "$line" | mail -s "Alerte disque $(hostname)" $ALERT_EMAIL; done

# Services critiques
for svc in nginx ssh mariadb; do
  systemctl is-active --quiet $svc || \
    echo "ALERTE: $svc est arrêté" | mail -s "Service DOWN $(hostname)" $ALERT_EMAIL
done

Cron — Syntaxe et exemples

Expression cronDescription
0 2 * * *Tous les jours à 02h00 (ex: sauvegarde nocturne)
*/5 * * * *Toutes les 5 minutes (ex: monitoring)
0 0 * * 1Chaque lundi à minuit (ex: rapport hebdo)
0 6 * * 1-5Du lundi au vendredi à 06h00
30 8 1 * *Le 1er de chaque mois à 08h30
@rebootAu démarrage du système
@dailyUne fois par jour (équiv. 0 0 * * *)
@weeklyUne fois par semaine

Ansible — Playbook de déploiement

💡
Idempotence : un playbook Ansible bien écrit peut être rejoué plusieurs fois sans effets secondaires. Utiliser --check pour simuler avant d'exécuter.
deploy-webserver.yml
---
- name: Déploiement serveur web complet
  hosts: webservers
  become: yes

  vars:
    app_name: monapp
    app_port: 8080
    nginx_user: www-data

  tasks:
    - name: Mettre à jour les paquets
      apt:
        update_cache: yes
        cache_valid_time: 3600

    - name: Installer Nginx et PHP
      apt:
        name:
          - nginx
          - php8.2-fpm
          - php8.2-mysql
        state: present

    - name: Copier la configuration Nginx
      template:
        src: templates/nginx.conf.j2
        dest: /etc/nginx/sites-available/{{ app_name }}
        owner: root
        mode: '0644'
      notify: Reload Nginx

    - name: Activer le site
      file:
        src: /etc/nginx/sites-available/{{ app_name }}
        dest: /etc/nginx/sites-enabled/{{ app_name }}
        state: link

    - name: S'assurer que Nginx est démarré
      systemd:
        name: nginx
        state: started
        enabled: yes

  handlers:
    - name: Reload Nginx
      systemd:
        name: nginx
        state: reloaded
inventory.ini
[webservers]
web1 ansible_host=192.168.1.10
web2 ansible_host=192.168.1.11

[databases]
db1 ansible_host=192.168.1.20

[all:vars]
ansible_user=admin
ansible_ssh_private_key_file=~/.ssh/id_ed25519
ansible_python_interpreter=/usr/bin/python3
Commande AnsibleDescription
ansible all -m pingTester la connectivité vers tous les hôtes
ansible-playbook deploy.yml --checkDry-run : simuler sans appliquer
ansible-playbook deploy.yml --tags nginxExécuter uniquement les tâches tagguées "nginx"
ansible-playbook deploy.yml -l web1Limiter l'exécution à l'hôte web1
ansible-vault encrypt secrets.ymlChiffrer un fichier de variables sensibles
ansible-vault decrypt secrets.ymlDéchiffrer (avec le mot de passe vault)
ansible all -m shell -a "uptime"Exécuter une commande shell ad-hoc

Python — Script réseau avec Netmiko

network-audit.py
from netmiko import ConnectHandler
import json

# Définition de l'équipement
device = {{
    'device_type': 'cisco_ios',
    'host':        '192.168.1.1',
    'username':    'admin',
    'password':    'P@ssw0rd!',
    'port':        22,
}}

# Connexion et récupération des données
with ConnectHandler(**device) as conn:
    # Exécuter des commandes show
    interfaces = conn.send_command('show ip interface brief', use_textfsm=True)
    routes     = conn.send_command('show ip route', use_textfsm=True)

    print("=== Interfaces ===")
    for intf in interfaces:
        print(f"{{intf['intf']}}: {{intf['ipaddr']}} — {{intf['status']}}")

    # Envoyer des commandes de configuration
    config_cmds = [
        'interface Loopback0',
        'description GESTION',
        'ip address 10.255.0.1 255.255.255.255',
    ]
    conn.send_config_set(config_cmds)
    conn.save_config()
    print("Configuration appliquée et sauvegardée.")
Ajouter Les Fibrés à mes sources préférées
Retrouvez plus souvent nos guides dans vos résultats Google