- 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
389 lines
8.8 KiB
Markdown
389 lines
8.8 KiB
Markdown
# 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)
|