Add Ansible integration for device management and deployment automation

- Added ansible/ directory with playbooks for:
  * deploy.yml: Update applications on devices from git
  * commands.yml: Execute arbitrary commands on devices
  * system_update.yml: OS updates and health checks
  * inventory.ini: Device and group configuration
  * README.md: Comprehensive Ansible guide
  * requirements.txt: Installation instructions

- Added ansible_integration.py: Python module wrapping Ansible operations
- Added utils_ansible.py: Updated utilities using Ansible instead of HTTP commands

Key benefits:
- Idempotent operations with error recovery
- Comprehensive logging and backup
- Multi-device orchestration
- Better reliability and control
- Replaces unreliable direct HTTP command execution
This commit is contained in:
Developer
2025-12-18 13:59:48 +02:00
parent 376240fb06
commit cb52e67afa
8 changed files with 1807 additions and 0 deletions

388
ansible/README.md Normal file
View File

@@ -0,0 +1,388 @@
# Ansible Integration for Server_Monitorizare
This directory contains Ansible playbooks and configuration for managing Prezenta Work devices remotely.
## Overview
The Ansible integration replaces direct HTTP command execution with a more robust, scalable solution:
### **Before (HTTP-based)**
```
Server → HTTP Request → Device (/execute_command endpoint)
Problems:
- No idempotency
- Hard to track what happened
- No built-in error recovery
- Limited command execution control
```
### **After (Ansible-based)**
```
Server → Ansible Playbook → Device (SSH)
Benefits:
- Idempotent operations
- Comprehensive logging
- Built-in error handling & retry logic
- Structured playbooks
- Multi-device orchestration
- Backup and rollback capability
```
## Files
### Configuration
- **inventory.ini** - Defines all devices, groups, and variables
### Playbooks
- **deploy.yml** - Deploy application updates (pull from git, restart service)
- **commands.yml** - Execute arbitrary commands on devices
- **system_update.yml** - System maintenance (OS updates, health checks)
### Python Integration
- **ansible_integration.py** - Python module for Ansible automation
- **utils_ansible.py** - Updated utilities using Ansible (replaces old utils.py)
## Setup
### 1. Install Ansible on Server
```bash
# On Server_Monitorizare (Ubuntu/Debian)
sudo apt-get update
sudo apt-get install -y ansible
# Verify installation
ansible --version
```
### 2. Configure Inventory
Edit `inventory.ini` and add your devices:
```ini
[prezenta_devices]
device_1 ansible_host=192.168.1.20
device_2 ansible_host=192.168.1.21
device_3 ansible_host=192.168.1.22
```
### 3. Setup SSH Keys (Optional but Recommended)
For password-less authentication:
```bash
# Generate SSH keys if not present
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -N ""
# Copy public key to each device
ssh-copy-id -i ~/.ssh/id_rsa.pub pi@192.168.1.20
ssh-copy-id -i ~/.ssh/id_rsa.pub pi@192.168.1.21
ssh-copy-id -i ~/.ssh/id_rsa.pub pi@192.168.1.22
```
Update inventory.ini to use SSH key auth:
```ini
[all:vars]
ansible_user=pi
ansible_ssh_private_key_file=~/.ssh/id_rsa
ansible_ssh_common_args='-o StrictHostKeyChecking=no'
```
### 4. Test Connectivity
```bash
# Test all devices
ansible all -i inventory.ini -m ping
# Test specific group
ansible prezenta_devices -i inventory.ini -m ping
```
## Usage
### From Command Line
#### Deploy Updates
```bash
# Deploy dev branch to all devices
ansible-playbook -i inventory.ini deploy.yml \
-e git_branch=dev \
-e backup_before_deploy=true \
-e restart_service=true
# Deploy to specific device
ansible-playbook -i inventory.ini deploy.yml \
--limit device_1 \
-e git_branch=dev
```
#### Execute Commands
```bash
# Execute command on all devices
ansible-playbook -i inventory.ini commands.yml \
-e command="ps aux | grep prezenta"
# Execute on specific device
ansible-playbook -i inventory.ini commands.yml \
--limit device_1 \
-e command="systemctl status prezenta"
```
#### System Update
```bash
# Update Python packages and perform health check
ansible-playbook -i inventory.ini system_update.yml \
-e update_python_packages=true \
-e perform_health_check=true
# Also update OS packages
ansible-playbook -i inventory.ini system_update.yml \
-e update_os_packages=true \
-e update_python_packages=true \
-e perform_health_check=true
```
### From Python Code
```python
from utils_ansible import (
deploy_updates_to_device,
deploy_updates_to_all_devices,
execute_command_on_device,
system_update_device,
get_device_status,
get_execution_logs
)
# Deploy to specific device
result = deploy_updates_to_device('device_1', git_branch='dev')
print(result)
# Deploy to all devices
result = deploy_updates_to_all_devices(git_branch='dev')
print(result)
# Execute command
result = execute_command_on_device('device_1', 'systemctl status prezenta')
print(result)
# System update
result = system_update_device('device_1', update_python=True, health_check=True)
print(result)
# Get device status
result = get_device_status('device_1')
print(result)
# Get recent logs
logs = get_execution_logs(limit=10)
print(logs)
```
### In Flask Routes
Update your Flask routes to use the new Ansible-based utilities:
```python
from flask import request, jsonify
from utils_ansible import (
deploy_updates_to_device,
execute_command_on_device,
get_device_status
)
@app.route('/api/deploy', methods=['POST'])
def deploy_api():
data = request.json
device = data.get('device')
branch = data.get('branch', 'dev')
result = deploy_updates_to_device(device, git_branch=branch)
return jsonify(result)
@app.route('/api/command', methods=['POST'])
def command_api():
data = request.json
device = data.get('device')
command = data.get('command')
result = execute_command_on_device(device, command)
return jsonify(result)
@app.route('/api/device/<device>/status', methods=['GET'])
def device_status_api(device):
result = get_device_status(device)
return jsonify(result)
```
## Playbook Details
### deploy.yml
**What it does:**
1. Backs up current code (optional)
2. Fetches latest from git repository
3. Checks out specified branch
4. Pulls latest changes
5. Verifies syntax
6. Restarts application service
7. Verifies service is running
8. Logs deployment
**Example:**
```bash
ansible-playbook deploy.yml -e git_branch=dev -e backup_before_deploy=true
```
**Output Locations:**
- Backups: `/srv/prezenta_work/backups/`
- Logs: `./logs/deploy_YYYYMMDD_HHMMSS.log`
### commands.yml
**What it does:**
1. Executes command with specified user
2. Captures output and errors
3. Logs command in device's command history
4. Returns result
**Example:**
```bash
ansible-playbook commands.yml -e command="sudo systemctl restart prezenta"
```
**Output Locations:**
- Logs: `./logs/command_DEVICE_YYYYMMDD_HHMMSS.log`
- Device log: `/srv/prezenta_work/data/command_history.log`
### system_update.yml
**What it does:**
1. Gathers system facts
2. Updates OS packages (optional)
3. Updates Python packages
4. Checks service status
5. Performs health checks (disk, memory, CPU temp)
6. Logs results
7. Reboots if needed (optional)
**Example:**
```bash
ansible-playbook system_update.yml \
-e update_os_packages=false \
-e update_python_packages=true \
-e perform_health_check=true
```
**Output Locations:**
- Logs: `./logs/system_update_YYYYMMDD_HHMMSS.log`
- Device log: `/srv/prezenta_work/data/system_update.log`
## Execution Logs
Logs are stored in `ansible/logs/` directory:
```bash
# View recent logs
ls -lht ansible/logs/ | head -10
# Follow live deployment
tail -f ansible/logs/deploy_*.log
# Search logs
grep "error\|fail" ansible/logs/*.log
```
## Troubleshooting
### SSH Connection Issues
```bash
# Test SSH manually
ssh -i ~/.ssh/id_rsa pi@192.168.1.20
# Test with verbose output
ansible device_1 -i inventory.ini -m ping -vvv
```
### Ansible Module Errors
```bash
# Run with increased verbosity
ansible-playbook deploy.yml -vvv
```
### Device Not Found in Inventory
```bash
# List all hosts
ansible all -i inventory.ini --list-hosts
# List specific group
ansible prezenta_devices -i inventory.ini --list-hosts
```
## Security Considerations
1. **SSH Keys**: Use SSH key authentication instead of passwords
2. **Inventory**: Don't commit inventory.ini with passwords to git
3. **Ansible Vault**: Use for sensitive data:
```bash
ansible-vault create secrets.yml
ansible-playbook deploy.yml -e @secrets.yml --ask-vault-pass
```
4. **Firewall**: Ensure SSH (port 22) is open on devices
## Performance Tips
1. **Parallel Execution**: Run playbooks on multiple devices
```bash
ansible-playbook deploy.yml --forks 5
```
2. **Task Caching**: Avoid unnecessary updates
```bash
# Playbooks already use idempotent operations
```
3. **Logging**: Monitor log files for issues
```bash
# Compress old logs
gzip ansible/logs/deploy_*.log
```
## Migration from HTTP Commands
**Old (HTTP-based):**
```python
def execute_command_on_device(device_ip, command):
url = f"http://{device_ip}:80/execute_command"
response = requests.post(url, json={"command": command})
return response.json()
```
**New (Ansible-based):**
```python
from utils_ansible import execute_command_on_device
result = execute_command_on_device('device_hostname', command)
return result
```
## Next Steps
1. Install Ansible on Server_Monitorizare
2. Configure inventory.ini with your devices
3. Set up SSH key authentication
4. Test connectivity with `ansible all -m ping`
5. Create first deployment
6. Update Flask routes to use new utils_ansible
7. Monitor logs in `ansible/logs/`
## Documentation
For more information on Ansible:
- [Ansible Documentation](https://docs.ansible.com/)
- [Playbook Syntax](https://docs.ansible.com/ansible/latest/reference_appendices/playbooks_keywords.html)
- [Modules Reference](https://docs.ansible.com/ansible/latest/modules/modules_by_category.html)