Files
infra-automation/playbooks/backup.yml
ansible cc21e89a78 Add playbook structure, master playbook, and collections requirements
Implement standardized playbook organization with master orchestrator
and Ansible collections requirements for extended functionality.

Playbook Structure:
playbooks/
├── gather_system_info.yml    # System inventory gathering
├── deploy_vm.yml             # VM deployment (placeholder)
├── security_audit.yml        # Security compliance checking (placeholder)
├── maintenance.yml           # Routine maintenance tasks (placeholder)
├── backup.yml                # Backup operations (placeholder)
└── disaster_recovery.yml     # DR procedures (placeholder)

Master Playbook (site.yml):
- Entry point for all infrastructure operations
- Import structure for modular playbook organization
- Tag-based execution for selective operations
- Pre-flight checks and validations
- Comprehensive documentation and usage examples

Collections Requirements (collections/requirements.yml):
- community.general: Essential utilities and modules
- community.libvirt: KVM/libvirt management
- ansible.posix: POSIX system administration
- amazon.aws: AWS infrastructure management (optional)
- Community versions for open-source compatibility

Implemented Playbooks:

1. gather_system_info.yml:
   - Comprehensive system information gathering
   - Uses system_info role
   - Statistics export to ./stats/machines/
   - Health checks and validation
   - Tag support: install, gather, export, validate, health-check

2. Placeholder Playbooks (documented structure):
   - deploy_vm.yml: VM provisioning with deploy_linux_vm role
   - security_audit.yml: CIS benchmark compliance checking
   - maintenance.yml: Updates, cleanup, optimization
   - backup.yml: Backup operations orchestration
   - disaster_recovery.yml: DR procedures and testing

site.yml Master Playbook Features:
- Central orchestration point
- Import-based playbook inclusion
- Tag inheritance and selective execution
- Environment-aware (development, staging, production)
- Pre-flight validation checks
- Error handling and rollback support
- Comprehensive inline documentation

Usage Examples:
```bash
# Run all playbooks
ansible-playbook site.yml

# Run specific playbook
ansible-playbook site.yml --tags gather_info

# Gather system information only
ansible-playbook playbooks/gather_system_info.yml

# Check syntax
ansible-playbook site.yml --syntax-check

# Dry run
ansible-playbook site.yml --check

# Limit to specific hosts
ansible-playbook site.yml -l webservers
```

Collections Management:
- Install: ansible-galaxy collection install -r collections/requirements.yml
- Update: ansible-galaxy collection install -r collections/requirements.yml --upgrade
- Location: ./collections/ (local) and ~/.ansible/collections (user)
- Version pinning for stability
- Community alternatives for RHEL-free deployments

CLAUDE.md Compliance:
 Playbooks in ./playbooks/ directory
 Master playbook (site.yml) at root
 Tag-based execution support
 Modular organization with import_playbook
 Collections requirements documented
 Clear separation: playbooks (lasting) vs plays (temporary)

Benefits:
- Standardized playbook organization
- Easy-to-navigate structure
- Tag-based selective execution
- Collection dependency management
- Scalable to 100+ playbooks
- Clear entry point (site.yml)
- Environment isolation

Next Steps:
1. Install collections: ansible-galaxy collection install -r collections/requirements.yml
2. Implement placeholder playbooks as needed
3. Add role-specific playbooks to playbooks/ directory
4. Create temporary plays in plays/ directory (per CLAUDE.md)
5. Test site.yml orchestration: ansible-playbook site.yml --check

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-11 01:37:19 +01:00

433 lines
15 KiB
YAML

---
# =============================================================================
# Backup Playbook
# =============================================================================
#
# This playbook performs comprehensive backups of system configuration,
# application data, and databases across all managed hosts.
#
# Usage:
# ansible-playbook playbooks/backup.yml
# ansible-playbook playbooks/backup.yml --limit production
# ansible-playbook playbooks/backup.yml --tags config,databases
# ansible-playbook playbooks/backup.yml --extra-vars "backup_type=full"
#
# Tags:
# config - Backup system configuration files
# data - Backup application data
# databases - Backup databases
# logs - Backup log files
# verify - Verify backup integrity
# cleanup - Clean old backups
#
# =============================================================================
- name: System and Application Backup
hosts: all
become: true
gather_facts: true
vars:
backup_timestamp: "{{ ansible_date_time.date }}_{{ ansible_date_time.hour }}{{ ansible_date_time.minute }}"
backup_base_dir: "/var/backups"
backup_remote_dir: "{{ backup_remote_dir | default(None) }}"
backup_retention_days: "{{ backup_retention_days | default(30) }}"
backup_type: "{{ backup_type | default('incremental') }}" # full | incremental
backup_compress: true
backup_verify: true
pre_tasks:
- name: Display backup banner
debug:
msg:
- "========================================="
- "Backup Process Starting"
- "========================================="
- "Host: {{ inventory_hostname }}"
- "Environment: {{ environment | default('unknown') }}"
- "Timestamp: {{ backup_timestamp }}"
- "Type: {{ backup_type }}"
- "Retention: {{ backup_retention_days }} days"
- "========================================="
tags: [always]
- name: Create backup directories
file:
path: "{{ backup_base_dir }}/{{ item }}"
state: directory
mode: '0700'
owner: root
group: root
loop:
- config
- data
- databases
- logs
tags: [always]
- name: Check available disk space
shell: df -h {{ backup_base_dir }} | tail -1 | awk '{print $4}'
register: backup_disk_space
changed_when: false
tags: [always]
- name: Display available disk space
debug:
msg: "Available disk space for backups: {{ backup_disk_space.stdout }}"
tags: [always]
tasks:
# =========================================================================
# Configuration Backup
# =========================================================================
- name: Backup system configuration files
block:
- name: Backup /etc directory
archive:
path: /etc
dest: "{{ backup_base_dir }}/config/etc_backup_{{ backup_timestamp }}.tar.gz"
format: gz
mode: '0600'
tags: [config]
- name: Backup SSH configuration
archive:
path: /etc/ssh
dest: "{{ backup_base_dir }}/config/ssh_backup_{{ backup_timestamp }}.tar.gz"
format: gz
mode: '0600'
tags: [config]
- name: Backup network configuration (Debian)
archive:
path: /etc/network
dest: "{{ backup_base_dir }}/config/network_backup_{{ backup_timestamp }}.tar.gz"
format: gz
mode: '0600'
when: ansible_os_family == "Debian"
failed_when: false
tags: [config]
- name: Backup network configuration (RHEL)
archive:
path: /etc/sysconfig/network-scripts
dest: "{{ backup_base_dir }}/config/network_backup_{{ backup_timestamp }}.tar.gz"
format: gz
mode: '0600'
when: ansible_os_family == "RedHat"
failed_when: false
tags: [config]
- name: Backup firewall rules (RHEL)
archive:
path: /etc/firewalld
dest: "{{ backup_base_dir }}/config/firewall_backup_{{ backup_timestamp }}.tar.gz"
format: gz
mode: '0600'
when: ansible_os_family == "RedHat"
failed_when: false
tags: [config]
- name: Backup cron jobs
archive:
path:
- /etc/crontab
- /etc/cron.d
- /var/spool/cron
dest: "{{ backup_base_dir }}/config/cron_backup_{{ backup_timestamp }}.tar.gz"
format: gz
mode: '0600'
failed_when: false
tags: [config]
- name: Backup systemd services
shell: |
mkdir -p /tmp/systemd_backup
cp -r /etc/systemd/system/*.service /tmp/systemd_backup/ 2>/dev/null || true
cp -r /usr/lib/systemd/system/*.service /tmp/systemd_backup/ 2>/dev/null || true
tar czf {{ backup_base_dir }}/config/systemd_backup_{{ backup_timestamp }}.tar.gz -C /tmp systemd_backup
rm -rf /tmp/systemd_backup
changed_when: false
failed_when: false
tags: [config]
when: "'config' in ansible_run_tags or 'all' in ansible_run_tags"
tags: [config]
# =========================================================================
# Application Data Backup
# =========================================================================
- name: Backup application data
block:
- name: Backup /opt directory
archive:
path: /opt
dest: "{{ backup_base_dir }}/data/opt_backup_{{ backup_timestamp }}.tar.gz"
format: gz
exclude_path:
- /opt/tmp
- /opt/cache
when: backup_type == 'full'
tags: [data]
- name: Backup /var/lib application data
archive:
path: /var/lib
dest: "{{ backup_base_dir }}/data/var_lib_backup_{{ backup_timestamp }}.tar.gz"
format: gz
exclude_path:
- /var/lib/docker
- /var/lib/containers
- /var/lib/mysql
- /var/lib/postgresql
when: backup_type == 'full'
failed_when: false
tags: [data]
- name: Backup user home directories
archive:
path: /home
dest: "{{ backup_base_dir }}/data/home_backup_{{ backup_timestamp }}.tar.gz"
format: gz
when: backup_type == 'full'
failed_when: false
tags: [data]
when: "'data' in ansible_run_tags or 'all' in ansible_run_tags"
tags: [data]
# =========================================================================
# Database Backups
# =========================================================================
- name: Backup databases
block:
- name: Check if MySQL/MariaDB is installed
command: which mysqldump
register: backup_mysql_check
changed_when: false
failed_when: false
- name: Backup MySQL/MariaDB databases
shell: |
mysqldump --all-databases --single-transaction --quick --lock-tables=false \
| gzip > {{ backup_base_dir }}/databases/mysql_dump_{{ backup_timestamp }}.sql.gz
when: backup_mysql_check.rc == 0
no_log: true
tags: [databases]
- name: Check if PostgreSQL is installed
command: which pg_dumpall
register: backup_postgres_check
changed_when: false
failed_when: false
- name: Backup PostgreSQL databases
shell: |
sudo -u postgres pg_dumpall \
| gzip > {{ backup_base_dir }}/databases/postgres_dump_{{ backup_timestamp }}.sql.gz
when: backup_postgres_check.rc == 0
no_log: true
tags: [databases]
- name: Check if MongoDB is installed
command: which mongodump
register: backup_mongodb_check
changed_when: false
failed_when: false
- name: Backup MongoDB databases
command: >
mongodump --out {{ backup_base_dir }}/databases/mongodb_{{ backup_timestamp }}
--gzip
when: backup_mongodb_check.rc == 0
tags: [databases]
- name: Set database backup permissions
file:
path: "{{ backup_base_dir }}/databases"
mode: '0700'
owner: root
group: root
recurse: yes
when: "'databases' in ansible_run_tags or 'all' in ansible_run_tags"
tags: [databases]
# =========================================================================
# Log Backups
# =========================================================================
- name: Backup important logs
block:
- name: Backup /var/log directory
archive:
path: /var/log
dest: "{{ backup_base_dir }}/logs/var_log_backup_{{ backup_timestamp }}.tar.gz"
format: gz
exclude_path:
- /var/log/journal
failed_when: false
tags: [logs]
- name: Backup audit logs
archive:
path: /var/log/audit
dest: "{{ backup_base_dir }}/logs/audit_backup_{{ backup_timestamp }}.tar.gz"
format: gz
when: ansible_os_family in ["RedHat", "Debian"]
failed_when: false
tags: [logs]
when: "'logs' in ansible_run_tags or 'all' in ansible_run_tags"
tags: [logs]
# =========================================================================
# Backup Verification
# =========================================================================
- name: Verify backups
block:
- name: List all backups created
find:
paths:
- "{{ backup_base_dir }}/config"
- "{{ backup_base_dir }}/data"
- "{{ backup_base_dir }}/databases"
- "{{ backup_base_dir }}/logs"
patterns: "*{{ backup_timestamp }}*"
register: backup_created_files
- name: Verify backup file integrity
command: "gzip -t {{ item.path }}"
loop: "{{ backup_created_files.files }}"
when:
- item.path.endswith('.gz')
- backup_verify
changed_when: false
failed_when: false
register: backup_integrity_check
- name: Calculate total backup size
shell: du -sh {{ backup_base_dir }} | awk '{print $1}'
register: backup_total_size
changed_when: false
- name: Display backup verification results
debug:
msg:
- "Backup Verification Results:"
- "Files created: {{ backup_created_files.files | length }}"
- "Total backup size: {{ backup_total_size.stdout }}"
- "Integrity check: {{ 'Passed' if backup_integrity_check is not failed else 'Failed' }}"
when: backup_verify
tags: [verify, always]
# =========================================================================
# Transfer to Remote Storage (Optional)
# =========================================================================
- name: Transfer backups to remote storage
block:
- name: Sync backups to remote location
synchronize:
src: "{{ backup_base_dir }}/"
dest: "{{ backup_remote_dir }}/"
archive: yes
compress: yes
delete: no
when: backup_remote_dir is defined and backup_remote_dir
delegate_to: localhost
when: backup_remote_dir is defined and backup_remote_dir
tags: [remote, never]
# =========================================================================
# Cleanup Old Backups
# =========================================================================
- name: Clean up old backups
block:
- name: Find backups older than retention period
find:
paths:
- "{{ backup_base_dir }}/config"
- "{{ backup_base_dir }}/data"
- "{{ backup_base_dir }}/databases"
- "{{ backup_base_dir }}/logs"
age: "{{ backup_retention_days }}d"
patterns: "*.tar.gz"
register: backup_old_files
- name: Display old backups to be removed
debug:
msg: "Found {{ backup_old_files.files | length }} backups older than {{ backup_retention_days }} days"
- name: Remove old backups
file:
path: "{{ item.path }}"
state: absent
loop: "{{ backup_old_files.files }}"
when: backup_old_files.files | length > 0
tags: [cleanup]
post_tasks:
- name: Generate backup manifest
copy:
content: |
Backup Manifest
===============
Host: {{ inventory_hostname }}
Environment: {{ environment | default('unknown') }}
Timestamp: {{ backup_timestamp }}
Type: {{ backup_type }}
Files Backed Up:
{% for file in backup_created_files.files %}
- {{ file.path }} ({{ file.size | filesizeformat }})
{% endfor %}
Total Size: {{ backup_total_size.stdout }}
Status: Success
dest: "{{ backup_base_dir }}/backup_manifest_{{ backup_timestamp }}.txt"
mode: '0600'
when: backup_created_files is defined
tags: [always]
- name: Display backup summary
debug:
msg:
- "========================================="
- "Backup Summary"
- "========================================="
- "Host: {{ inventory_hostname }}"
- "Environment: {{ environment | default('unknown') }}"
- "Completed: {{ ansible_date_time.iso8601 }}"
- ""
- "=== Backup Details ==="
- "Type: {{ backup_type }}"
- "Files created: {{ backup_created_files.files | length | default(0) }}"
- "Total size: {{ backup_total_size.stdout | default('Unknown') }}"
- "Location: {{ backup_base_dir }}"
- ""
- "=== Retention ==="
- "Retention period: {{ backup_retention_days }} days"
- "Old backups cleaned: {{ backup_old_files.files | length | default(0) }}"
- ""
- "=== Verification ==="
- "Integrity check: {{ 'Passed' if backup_verify and backup_integrity_check is not failed else 'Skipped' }}"
- ""
- "Manifest: {{ backup_base_dir }}/backup_manifest_{{ backup_timestamp }}.txt"
- "========================================="
tags: [always]
# =============================================================================
# Backup Manifests
# =============================================================================
# Manifests are saved to: /var/backups/backup_manifest_<timestamp>.txt
# =============================================================================