Add monitoring and backup roles, enhancing infrastructure management capabilities. Introduce Proxmox VM creation playbook for automated VM provisioning. Update Makefile with new commands for monitoring and backup tasks. Enhance README.md with detailed usage instructions for new features, including automated backups and system monitoring tools. Refactor existing roles for improved organization and clarity, ensuring compatibility across various systems.

This commit is contained in:
ilia 2025-09-07 22:17:22 -04:00
parent 00d660201a
commit 4621ea4674
41 changed files with 1069 additions and 577 deletions

26
.ansible-lint Normal file
View File

@ -0,0 +1,26 @@
# Ansible Lint Configuration
---
# Exclude patterns
exclude_paths:
- .cache/
- .github/
- .ansible/
# Skip specific rules
skip_list:
- yaml[line-length] # Allow longer lines in some cases
- name[casing] # Allow mixed case in task names
- args[module] # Skip args rule that causes "file name too long" issues
- var-naming[no-role-prefix] # Allow shorter variable names for readability
- risky-shell-pipe # Allow shell pipes in maintenance scripts
# Warn instead of error for these
warn_list:
- experimental # Allow experimental features
- jinja[spacing] # Allow flexible jinja spacing
# Don't try to decrypt vault files during linting
offline: true
# Verbosity level (0-2)
verbosity: 1

View File

View File

@ -1,4 +1,4 @@
.PHONY: help bootstrap lint test check apply dev local clean status tailscale tailscale-check tailscale-dev tailscale-status create-vault
.PHONY: help bootstrap lint test check apply dev local clean status tailscale tailscale-check tailscale-dev tailscale-status create-vault create-vm monitoring backup
.DEFAULT_GOAL := help
## Colors for output
@ -26,10 +26,12 @@ help: ## Show this help message
@echo " make apply # Run on all dev hosts"
@echo " make dev HOST=dev01 # Run on specific host"
@echo " make local # Run local playbook"
@echo " make maintenance # Run maintenance on all hosts"
@echo " make maintenance GROUP=dev # Run maintenance on dev group"
@echo " make maintenance HOST=dev01 # Run maintenance on specific host"
@echo " make maintenance CHECK=true # Dry-run maintenance on all hosts"
@echo " make maintenance # Run maintenance on all hosts"
@echo " make maintenance GROUP=dev # Run maintenance on dev group"
@echo " make maintenance HOST=dev01 # Run maintenance on specific host"
@echo " make maintenance CHECK=true # Dry-run maintenance on all hosts"
@echo " make maintenance VERBOSE=true # Run with verbose output"
@echo " make maintenance-verbose GROUP=dev # Verbose maintenance on dev group"
@echo ""
bootstrap: ## Install required collections and dependencies
@ -110,7 +112,7 @@ security: ## Run only security-related roles
ansible-playbook dev-playbook.yml --tags security
# Unified maintenance target with intelligent parameter detection
maintenance: ## Run maintenance (usage: make maintenance [GROUP=dev] [HOST=dev01] [SERIAL=1] [CHECK=true])
maintenance: ## Run maintenance (usage: make maintenance [GROUP=dev] [HOST=dev01] [SERIAL=1] [CHECK=true] [VERBOSE=true])
@$(MAKE) _maintenance-run
_maintenance-run:
@ -150,6 +152,11 @@ _maintenance-run:
echo "$(YELLOW)Running maintenance on $$DESCRIPTION...$(RESET)"; \
fi; \
\
if [ "$(VERBOSE)" = "true" ]; then \
ANSIBLE_CMD="$$ANSIBLE_CMD -v"; \
echo "$(BLUE)Running with verbose output...$(RESET)"; \
fi; \
\
if [ -n "$(GROUP)" ] && [ "$(GROUP)" != "dev" ] && [ "$(GROUP)" != "local" ]; then \
echo "$(BLUE)Available groups: dev, gitea, portainer, homepage, ansible, local$(RESET)"; \
fi; \
@ -166,6 +173,9 @@ maintenance-all: ## Run maintenance on all hosts (legacy alias)
maintenance-check: ## Dry-run maintenance (legacy alias, usage: make maintenance-check [GROUP=dev])
@$(MAKE) maintenance CHECK=true GROUP=$(GROUP)
maintenance-verbose: ## Run maintenance with verbose output (usage: make maintenance-verbose [GROUP=dev])
@$(MAKE) maintenance VERBOSE=true GROUP=$(GROUP)
docker: ## Install/configure Docker only
@echo "$(YELLOW)Running Docker setup...$(RESET)"
ansible-playbook dev-playbook.yml --tags docker
@ -304,8 +314,6 @@ ifndef HOST
endif
ansible-vault edit host_vars/$(HOST).yml
test-connectivity: ## Test network connectivity and SSH access to all hosts
@echo "$(BOLD)Connectivity Test$(RESET)"
@if [ -n "$(CURRENT_HOST)" ]; then \
@ -364,4 +372,19 @@ endif
create-vault: ## Create encrypted vault file for secrets (passwords, auth keys, etc.)
@echo "$(YELLOW)Creating vault file for storing secrets...$(RESET)"
ansible-vault create group_vars/all/vault.yml
@echo "$(GREEN)✓ Vault file created. Add your secrets here (e.g. vault_tailscale_auth_key)$(RESET)"
@echo "$(GREEN)✓ Vault file created. Add your secrets here (e.g. vault_tailscale_auth_key)$(RESET)"
create-vm: ## Create Ansible controller VM on Proxmox
@echo "$(YELLOW)Creating Ansible controller VM on Proxmox...$(RESET)"
ansible-playbook proxmox-create-vm.yml --ask-vault-pass
@echo "$(GREEN)✓ VM creation complete$(RESET)"
monitoring: ## Install monitoring tools on all machines
@echo "$(YELLOW)Installing monitoring tools...$(RESET)"
ansible-playbook -i hosts dev-playbook.yml --tags monitoring
@echo "$(GREEN)✓ Monitoring installation complete$(RESET)"
backup: ## Set up automated backups on all machines
@echo "$(YELLOW)Setting up automated backups...$(RESET)"
ansible-playbook -i hosts dev-playbook.yml --tags backup
@echo "$(GREEN)✓ Backup setup complete$(RESET)"

453
README.md
View File

@ -1,31 +1,42 @@
# Ansible Development Environment Setup
# Ansible Infrastructure Management
This Ansible playbook automates the setup of development environments across multiple machines.
This Ansible project provides comprehensive infrastructure automation for development environments, server management, and VM provisioning across multiple machines and platforms.
## 🏗️ Architecture
### Host Groups
- `dev`: Development machines (dev01, bottom, debianDesktopVM)
- `gitea`: Gitea server
- `portainer`: Portainer container management
- `homepage`: Homepage dashboard
- `gitea`: Gitea server (Alpine Linux)
- `portainer`: Portainer container management (Alpine Linux)
- `homepage`: Homepage dashboard (Debian)
- `ansible`: Ansible control node
- `local`: Local machine management
### Roles
#### Core Roles
- **`maintenance`**: System updates, package cleanup, and reboots
#### Core Infrastructure Roles
- **`maintenance`**: System updates, package cleanup, and automated reboots
- **`base`**: Core system packages, security tools, and system hardening
- **`ssh`**: SSH server hardening and firewall configuration
- **`user`**: User management and configuration
#### Development & Shell Roles
- **`development`**: Development tools (git, nodejs, build-essential, python3)
- **`shell`**: Shell configuration (zsh + oh-my-zsh + powerlevel10k)
- **`docker`**: Docker CE installation and user configuration
- **`ssh`**: SSH server and firewall configuration
- **`user`**: User management
#### Application Roles
- **`applications`**: Desktop applications (Brave, LibreOffice, Redshift, Evince)
- **`snap`**: Snap daemon and snap applications (VSCode, Cursor)
#### Network & Monitoring Roles
- **`tailscale`**: VPN mesh networking across all machines
- **`monitoring`**: System monitoring tools and scripts
- **`backup`**: Automated backup solutions (✨ NEW)
#### Infrastructure Roles
- **`proxmox_vm`**: Proxmox VM creation and management (✨ NEW)
## 🚀 Usage
### Quick Start with Makefile (Recommended)
@ -36,7 +47,7 @@ make bootstrap
# Test everything
make test
# Dry run to see what would change
# Dry run to see what would change
make check
# Apply to all development hosts
@ -49,6 +60,53 @@ make dev HOST=dev01
make local
```
### New Infrastructure Features
#### Proxmox VM Creation (✨ NEW)
```bash
# Create new VMs on Proxmox
make create-vm
# Or manually:
ansible-playbook proxmox-create-vm.yml
```
#### Automated Backups (✨ NEW)
```bash
# Deploy backup system
make backup
# Includes:
# - Daily home directory backups (2:00 AM)
# - Daily system config backups (2:30 AM)
# - 7-day retention for home, 30-day for system
# - Automated cleanup and logging
```
#### System Monitoring (✨ NEW)
```bash
# Deploy monitoring tools
make monitoring
# Includes:
# - Advanced system monitoring (btop, iotop, nethogs)
# - Custom monitoring scripts
# - System information dashboards
# - Tailscale network status integration
```
#### Tailscale VPN Network
```bash
# Deploy Tailscale across all machines
make tailscale
# Check Tailscale status
make tailscale-status
# Deploy to development machines only
make tailscale-dev
```
### Prerequisites (Manual Setup)
```bash
# Install required collections
@ -56,10 +114,9 @@ ansible-galaxy collection install -r collections/requirements.yml
```
### Vault Password Setup
Host variables are encrypted with Ansible Vault. You have two options:
Host variables and sensitive data are encrypted with Ansible Vault:
#### Option 1: Vault Password File (Recommended)
Create a vault password file:
```bash
# Create the vault password file
echo "your_vault_password" > ~/.ansible-vault-pass
@ -67,49 +124,53 @@ chmod 600 ~/.ansible-vault-pass
```
#### Option 2: Interactive Password Prompt
Use `--ask-vault-pass` with each command to be prompted for the vault password.
Use `--ask-vault-pass` with each command.
### Basic Setup
### Vault Configuration
Create vault files with encrypted secrets:
```bash
# Run on all development machines (with vault password file)
ansible-playbook dev-playbook.yml
# Create/edit vault files
make create-vault
make edit-vault HOST=dev01
# Run on all development machines (interactive vault password)
ansible-playbook dev-playbook.yml --ask-vault-pass
# Run on specific host
ansible-playbook dev-playbook.yml --limit dev01
# Skip reboots for specific host
ansible-playbook dev-playbook.yml --limit bottom
# Required vault variables:
# - vault_tailscale_auth_key: "tskey-auth-your-key"
# - vault_proxmox_host: "proxmox-server-ip"
# - vault_proxmox_user: "root@pam"
# - vault_proxmox_password: "proxmox-password"
# - vault_vm_cipassword: "vm-user-password"
# - vault_ssh_public_key: "ssh-ed25519 AAAA..."
```
### Selective Execution with Tags
#### Using Makefile (Recommended)
```bash
# Security-related roles only
make security
# Infrastructure roles
make security # Security-related roles only
make monitoring # Monitoring tools only
make backup # Backup system only
# Development tools only
make docker
make shell
# Development tools
make docker # Docker installation only
make shell # Shell configuration only
make apps # Applications only
# Applications only
make apps
# Network services
make tailscale # VPN network setup
make tailscale-status # Check VPN status
# Maintenance (unified system)
make maintenance # All hosts
make maintenance GROUP=dev # Specific group
make maintenance HOST=dev01 # Specific host
make maintenance HOST=dev01 # Specific host
make maintenance CHECK=true # Dry-run all hosts
make maintenance GROUP=dev SERIAL=1 # Serial execution
# Check connectivity
make status
# Get detailed help
make help
# Infrastructure management
make create-vm # Create new Proxmox VMs
make status # Check connectivity
make facts # Gather system facts
```
#### Manual Commands
@ -117,49 +178,25 @@ make help
# Security-related roles only
ansible-playbook dev-playbook.yml --tags security
# Development tools only
# Development tools only
ansible-playbook dev-playbook.yml --tags development,docker
# Applications only
ansible-playbook dev-playbook.yml --tags apps
# Network services
ansible-playbook tailscale-playbook.yml
# Infrastructure provisioning
ansible-playbook proxmox-create-vm.yml
# Skip maintenance
ansible-playbook dev-playbook.yml --skip-tags maintenance
```
### Skip Reboots
Add `skip_reboot=true` to host variables:
```ini
[dev]
bottom ansible_host=10.0.10.156 ansible_user=beast skip_reboot=true
```
### Debug Output
Control debug information display with the `ansible_debug_output` variable:
```bash
# Default: No debug output (clean, production-ready output)
ansible-playbook dev-playbook.yml --limit dev01
# Enable debug output (shows detailed status information)
ansible-playbook dev-playbook.yml --limit dev01 -e "ansible_debug_output=true"
# Set permanently in group_vars/all.yml
ansible_debug_output: true
```
### Dry Run and Testing
```bash
# Using Makefile
make test # Lint + syntax check
make check # Dry run all hosts
make check-local # Dry run localhost
make quick # Test + check workflow
# Manual commands
ansible-playbook dev-playbook.yml --check # Check what would change
ansible-playbook dev-playbook.yml -v # Verbose output
```
### Playbook Overview
- **`dev-playbook.yml`**: Complete development environment setup
- **`local-playbook.yml`**: Local machine configuration
- **`tailscale-playbook.yml`**: VPN network deployment
- **`proxmox-create-vm.yml`**: VM provisioning on Proxmox
- **`maintenance-playbook.yml`**: System maintenance operations
## 🔧 Configuration
@ -168,11 +205,23 @@ ansible-playbook dev-playbook.yml -v # Verbose output
- `locale`: System locale (default: en_US.UTF-8)
- `ansible_debug_output`: Show debug information (default: false)
- `fail2ban_bantime`: Ban duration in seconds
- `fail2ban_findtime`: Time window for failures
- `fail2ban_findtime`: Time window for failures
- `fail2ban_maxretry`: Max failures before ban
### Tailscale Configuration
- `tailscale_auth_key`: Authentication key (stored in vault)
- `tailscale_accept_routes`: Accept subnet routes (default: true)
- `tailscale_accept_dns`: Accept DNS settings (default: true)
- `tailscale_ssh`: Enable SSH access through Tailscale (default: true)
### Backup Configuration (`roles/backup/defaults/main.yml`)
- `backup_enable_cron`: Enable automated backups (default: true)
- `backup_retention_days_home`: Home backup retention (default: 7)
- `backup_retention_days_system`: System backup retention (default: 30)
- `backup_users`: Users to backup (default: ['master', 'beast', 'ladmin', 'user'])
### SSH Configuration (`roles/ssh/defaults/main.yml`)
The SSH role provides comprehensive security hardening:
Comprehensive security hardening:
- `ssh_port`: SSH port (default: 22)
- `ssh_permit_root_login`: Root login setting (default: 'no')
- `ssh_password_authentication`: Password auth (default: 'no')
@ -180,32 +229,16 @@ The SSH role provides comprehensive security hardening:
- `ssh_allowed_users`: Restrict to specific users (default: [])
- `ssh_allowed_groups`: Restrict to specific groups (default: ['sudo', 'ssh'])
Override any setting in your host or group variables:
```yaml
# Example: Custom SSH port
ssh_port: 2222
# Example: Allow specific users
ssh_allowed_users: ['admin', 'deploy']
```
### Host Variables (`host_vars/`)
- `skip_reboot`: Skip automatic reboots
- Encrypted variables for sensitive data
### Proxmox VM Configuration (`roles/proxmox_vm/defaults/main.yml`)
- `vm_memory`: RAM allocation (default: 8192MB)
- `vm_cores`: CPU cores (default: 2)
- `vm_disk_size`: Disk size (default: 20G)
- `vm_iso`: Ubuntu Server ISO (default: ubuntu-24.04-live-server-amd64.iso)
- `vm_ciuser`: Default user (default: master)
## 🛡️ Security Features
### Fail2ban Configuration
- SSH brute force protection
- Configurable ban times and retry limits
- Email notifications (configured in template)
### UFW Firewall
- Deny-by-default policy
- SSH access allowed
- Automatic enablement
### SSH Hardening
### Comprehensive SSH Hardening
- Modern cryptographic algorithms (ChaCha20-Poly1305, AES-256-GCM)
- Secure key exchange (Curve25519, DH Group 16)
- Disabled password authentication
@ -213,10 +246,21 @@ ssh_allowed_users: ['admin', 'deploy']
- User/group access restrictions
- Configuration validation and automatic backup
### System Hardening
- Timezone and locale configuration
- Security package installation
- Modern CLI tools and system monitoring
### Fail2ban Integration
- SSH brute force protection
- Configurable ban times and retry limits
- Email notifications
### UFW Firewall
- Deny-by-default policy
- SSH access allowed
- Automatic enablement
### Tailscale VPN Security
- Zero-trust mesh networking
- End-to-end encryption
- SSH access through secure tunnel
- Subnet routing capabilities
## 📦 Installed Packages
@ -234,11 +278,24 @@ ssh_allowed_users: ['admin', 'deploy']
- `brave-browser`, `libreoffice`, `evince`, `redshift`
- `code` (VSCode), `cursor` (via snap)
### Docker
### Docker & Containers
- Docker CE with all components
- Docker Compose
- User added to docker group
### Backup Tools (✨ NEW)
- `rsync`, `borgbackup`, `rclone`, `restic`
- Automated backup scripts and cron jobs
### Monitoring Tools (✨ NEW)
- `htop`, `iotop`, `nethogs`, `btop`
- Custom system information scripts
- Network monitoring utilities
### VPN & Network
- `tailscale` - Mesh VPN networking
- Network utilities and monitoring
## 🔧 Modern CLI Tools
The base role installs modern replacements for traditional Unix tools:
@ -249,7 +306,7 @@ The base role installs modern replacements for traditional Unix tools:
rg "pattern" files/ # ripgrep - faster than grep
fd "filename" # fd-find - intuitive find replacement
# Data processing
# Data processing
jq '.key' file.json # JSON processor and formatter
yq '.key' file.yaml # YAML processor and formatter
@ -257,70 +314,76 @@ yq '.key' file.yaml # YAML processor and formatter
btop # Modern system monitor (better than htop)
tree directory/ # Directory structure visualization
# File operations
# File operations
tree -L 2 # Limit tree depth
rg -i "case insensitive" # Case-insensitive search
fd -e yml # Find only YAML files
jq -r '.items[].name' # Raw JSON output
```
### Integration Examples
```bash
# DevOps workflows
kubectl get pods -o json | jq '.items[].metadata.name'
docker ps --format json | jq '.Names'
rg "ansible.builtin" roles/ --type yaml
fd "main.yml" roles/ -x cat
```
## 🔄 Maintenance
## 🔄 Maintenance & Operations
### Unified Maintenance System
The maintenance system provides a single, intelligent command for all maintenance operations:
```bash
# Basic usage
make maintenance # Run on all hosts
make maintenance GROUP=dev # Run on specific group
make maintenance GROUP=dev # Run on specific group
make maintenance HOST=dev01 # Run on specific host
# Advanced options
make maintenance CHECK=true # Dry-run (safe testing)
make maintenance GROUP=dev SERIAL=1 # One host at a time
make maintenance GROUP=local # Local machine (auto-sudo)
# Legacy support (still works)
make maintenance-all # Same as: make maintenance
make maintenance-check GROUP=dev # Same as: make maintenance GROUP=dev CHECK=true
```
### Available Host Groups
- `dev`: Development machines (dev01, bottom, debianDesktopVM)
- `gitea`: Gitea server
- `portainer`: Portainer container management
- `homepage`: Homepage dashboard
- `ansible`: Ansible control node
- `local`: Localhost (with automatic sudo handling)
### Maintenance Features
The maintenance role handles:
- Package updates (`apt upgrade`)
- Unused package removal (`apt autoremove`)
- Cache cleanup (`apt autoclean`)
- Conditional reboots (respects `skip_reboot` setting)
- System information reporting
- Intelligent sudo password handling
### Direct Ansible Commands
### Backup Operations (✨ NEW)
```bash
# Using the dedicated maintenance playbook
ansible-playbook maintenance-playbook.yml -e "target_group=dev"
ansible-playbook maintenance-playbook.yml --limit "dev01"
ansible-playbook maintenance-playbook.yml --check --diff # Dry-run
# Deploy backup system
make backup
# Using tags with development playbook
ansible-playbook dev-playbook.yml --tags maintenance
ansible-playbook dev-playbook.yml --skip-tags maintenance
# Manual backup operations
sudo /opt/backups/scripts/backup-home.sh # Run home backup
sudo /opt/backups/scripts/backup-system.sh # Run system backup
# Check backup logs
tail -f /var/log/backups/home.log
tail -f /var/log/backups/system.log
```
### Monitoring Operations (✨ NEW)
```bash
# Deploy monitoring tools
make monitoring
# Use monitoring scripts
/usr/local/bin/monitoring/sysinfo # System information dashboard
/usr/local/bin/monitoring/netinfo # Network information
# System monitoring
btop # Interactive system monitor
```
### Tailscale Network Management
```bash
# Deploy VPN network
make tailscale
# Check status across all machines
make tailscale-status
# Manual Tailscale commands
tailscale status # Check connection status
tailscale ip # Show Tailscale IP
tailscale netcheck # Network connectivity check
```
### Infrastructure Provisioning (✨ NEW)
```bash
# Create new VMs on Proxmox
make create-vm
# Custom VM creation
ansible-playbook proxmox-create-vm.yml -e "vm_name=new-server vm_id=111"
```
## 🐛 Troubleshooting
@ -330,31 +393,32 @@ ansible-playbook dev-playbook.yml --skip-tags maintenance
1. **SSH Connection Issues**
- Check `ansible.cfg` SSH settings
- Verify host keys and user permissions
- Test Tailscale connectivity: `tailscale ping hostname`
2. **Package Installation Failures**
- Run with `-v` for verbose output
- Check internet connectivity on target hosts
2. **Vault Access Issues**
- Verify vault password file: `~/.ansible-vault-pass`
- Test vault decryption: `ansible-vault view host_vars/hostname.yml`
3. **Reboot Issues**
- Use `skip_reboot=true` for problematic hosts
- Check maintenance role handlers
3. **Tailscale Connection Issues**
- Check service status: `sudo systemctl status tailscaled`
- Verify auth key in vault
- Check firewall: `sudo ufw status`
4. **SSH Configuration Issues**
- Original config backed up to `/etc/ssh/sshd_config.backup`
- Test SSH config: `sudo sshd -t`
- Check SSH service: `sudo systemctl status ssh`
- Verify public key authentication is working before applying
4. **Proxmox VM Creation Issues**
- Verify Proxmox credentials in vault
- Check ISO availability: `pvesm list local --content iso`
- Ensure sufficient resources on Proxmox node
5. **Modern CLI Tools Missing**
- Check if snap is installed: `snap --version`
- For fd command: Symlink created at `/usr/local/bin/fd`
- Alternative: Use `fdfind` directly on Ubuntu systems
5. **Backup Issues**
- Check backup directories: `ls -la /opt/backups/`
- Review logs: `tail -f /var/log/backups/*.log`
- Verify cron jobs: `sudo crontab -l`
### Debug Commands
```bash
# Using Makefile
make status # Test connectivity to all hosts
make facts # Gather facts from all hosts
make facts # Gather facts from all hosts
make debug # Run with debug output
make verbose # Run with verbose output
@ -364,16 +428,13 @@ ansible dev -m setup # Check facts
ansible-playbook dev-playbook.yml --tags base # Run specific role
# Verify installations
ansible dev -m shell -a "jq --version" # Check jq installation
ansible dev -m shell -a "rg --version" # Check ripgrep installation
ansible dev -m shell -a "fd --version" # Check fd installation
ansible dev -m shell -a "sudo sshd -t" # Validate SSH config
ansible dev -m shell -a "tailscale status" # Check Tailscale
ansible dev -m shell -a "docker --version" # Check Docker
ansible dev -m shell -a "sudo sshd -t" # Validate SSH config
```
## 🛠️ Makefile Workflows
The included `Makefile` provides convenient shortcuts for common operations:
### Development Workflow
```bash
make bootstrap # Install collections
@ -382,10 +443,19 @@ make check # Dry run
make apply # Deploy to all hosts
```
### Infrastructure Management
```bash
make create-vm # Provision new VMs
make tailscale # Deploy VPN network
make monitoring # Deploy monitoring
make backup # Deploy backup system
```
### Host-Specific Operations
```bash
make dev HOST=dev01 # Deploy to specific host
make edit-vault HOST=dev01 # Edit encrypted host variables
make tailscale-dev # Deploy Tailscale to dev hosts only
```
### Maintenance and Utilities
@ -398,30 +468,35 @@ make install-tools # Install recommended CLI tools locally
Run `make help` for the complete list of available commands.
## 📝 File Structure
```
ansible/
├── ansible.cfg # Enhanced Ansible configuration
├── Makefile # Workflow automation with unified maintenance
├── hosts # Inventory file
├── dev-playbook.yml # Main development playbook
├── local-playbook.yml # Local machine setup
├── ansible.cfg # Enhanced Ansible configuration
├── Makefile # Workflow automation with unified maintenance
├── hosts # Inventory file
├── dev-playbook.yml # Main development playbook
├── local-playbook.yml # Local machine setup
├── tailscale-playbook.yml # VPN network deployment
├── proxmox-create-vm.yml # VM provisioning playbook
├── maintenance-playbook.yml # Dedicated maintenance playbook
├── collections/
└── requirements.yml # Required Ansible collections
│ └── requirements.yml # Required Ansible collections
├── group_vars/
└── all.yml # Global variables
├── host_vars/ # Host-specific variables (encrypted)
│ └── all.yml # Global variables and Tailscale config
├── host_vars/ # Host-specific variables (encrypted)
└── roles/
├── maintenance/ # System maintenance
├── base/ # Core system setup
├── development/ # Development tools
├── shell/ # Shell configuration (zsh + oh-my-zsh)
├── docker/ # Docker installation
├── ssh/ # SSH hardening and configuration
├── user/ # User management
├── applications/ # Desktop applications
└── snap/ # Snap applications
```
├── maintenance/ # System maintenance
├── base/ # Core system setup
├── development/ # Development tools
├── shell/ # Shell configuration (zsh + oh-my-zsh)
├── docker/ # Docker installation
├── ssh/ # SSH hardening and configuration
├── user/ # User management
├── applications/ # Desktop applications
├── snap/ # Snap applications
├── tailscale/ # VPN mesh networking
├── monitoring/ # System monitoring tools
├── backup/ # Automated backup solutions
└── proxmox_vm/ # VM provisioning on Proxmox
## 🤝 Contributing
@ -429,3 +504,5 @@ ansible/
2. Update documentation for new roles/tasks
3. Use proper handlers for service restarts
4. Follow existing naming conventions
5. Encrypt sensitive data with ansible-vault
6. Test across different OS distributions (Ubuntu, Debian, Alpine)

View File

@ -2,5 +2,7 @@
collections:
- name: community.general
version: ">=6.0.0"
- name: community.proxmox
version: ">=1.0.0"
- name: ansible.posix
version: ">=1.4.0"

View File

@ -13,6 +13,8 @@
- { role: applications, tags: ['applications', 'apps'] }
- { role: snap, tags: ['snap', 'apps'] }
- { role: tailscale, tags: ['tailscale', 'vpn'] }
- { role: monitoring, tags: ['monitoring'] }
# - { role: backup, tags: ['backup'] }
pre_tasks:
- name: Update apt cache

View File

@ -29,4 +29,4 @@ tailscale_auth_key: "{{ vault_tailscale_auth_key | default('') }}"
tailscale_accept_routes: true
tailscale_accept_dns: true
tailscale_ssh: true
tailscale_hostname: "{{ inventory_hostname }}"
tailscale_hostname: "{{ inventory_hostname }}"

View File

@ -14,6 +14,8 @@
- { role: applications, tags: ['applications', 'apps'] }
- { role: snap, tags: ['snap', 'apps'] }
- { role: tailscale, tags: ['tailscale', 'vpn'] }
- { role: monitoring, tags: ['monitoring'] }
# - { role: backup, tags: ['backup'] }
pre_tasks:
- name: Update apt cache

78
proxmox-create-vm.yml Normal file
View File

@ -0,0 +1,78 @@
---
- name: Create Ansible Controller VM on Proxmox
hosts: localhost
connection: local
gather_facts: false
vars:
# Proxmox connection (store credentials in vault)
proxmox_host: "{{ vault_proxmox_host }}"
proxmox_user: "{{ vault_proxmox_user }}"
proxmox_node: "{{ vault_proxmox_node | default('pve') }}"
# VM specs matching your current setup
vm_name: "ansible-control"
vm_id: 110
vm_memory: 8192 # 8GB (match current working setup)
vm_cores: 2 # 2 cores
vm_sockets: 1
vm_disk_size: "32G" # Bigger than current 8G
vm_storage: "local-lvm"
vm_network_bridge: "vmbr0"
# Ubuntu Server 24.04 LTS
vm_iso: "ubuntu-24.04-live-server-amd64.iso"
vm_iso_storage: "local"
# User configuration
vm_ciuser: "master"
vm_ssh_keys:
- "{{ vault_ssh_public_key }}" # Your SSH public key
vm_ip_config: "dhcp" # or set static: "10.0.10.110/24,gw=10.0.10.1"
vm_start_after_create: true
pre_tasks:
- name: Check if VM already exists
community.general.proxmox_kvm:
api_host: "{{ proxmox_host }}"
api_user: "{{ proxmox_user }}"
api_password: "{{ vault_proxmox_password }}"
vmid: "{{ vm_id }}"
state: current
register: vm_check
failed_when: false
- name: Display VM status
ansible.builtin.debug:
msg: |
VM {{ vm_name }} ({{ vm_id }}): {{ 'Already exists' if vm_check.status is defined else 'Will be created' }}
roles:
- { role: proxmox_vm, when: vm_check.status is not defined }
post_tasks:
- name: Wait for VM to be accessible via SSH
ansible.builtin.wait_for:
host: "{{ vm_ip_config.split('/')[0] if '/' in vm_ip_config else 'ansible-control.local' }}"
port: 22
timeout: 300
when:
- vm_check.status is not defined
- vm_start_after_create | bool
- vm_ip_config != "dhcp"
- name: Display next steps
ansible.builtin.debug:
msg: |
🎉 Ansible Controller VM Created Successfully!
Next steps:
1. The VM should be starting up now
2. Wait a few minutes for Ubuntu installation to complete
3. SSH to the VM: ssh {{ vm_ciuser }}@[VM-IP]
4. Run the local-playbook.yml to set it up as an Ansible controller
To find the VM IP (if using DHCP):
- Check Proxmox web interface
- Or run: qm guest cmd {{ vm_id }} network-get-interfaces

View File

@ -1 +0,0 @@
dependencies: []

View File

@ -0,0 +1,10 @@
---
# Backup role defaults
backup_enable_cron: true
backup_retention_days_home: 7
backup_retention_days_system: 30
backup_users:
- master
- beast
- ladmin
- user

View File

@ -0,0 +1,50 @@
---
- name: Install backup tools
ansible.builtin.apt:
name:
- rsync
- borgbackup
- rclone
- restic
state: present
- name: Create backup directories
ansible.builtin.file:
path: "{{ item }}"
state: directory
mode: '0755'
loop:
- /opt/backups
- /opt/backups/scripts
- /var/log/backups
- name: Deploy backup script for home directories
ansible.builtin.template:
src: backup-home.sh.j2
dest: /opt/backups/scripts/backup-home.sh
mode: '0755'
- name: Deploy backup script for system configs
ansible.builtin.template:
src: backup-system.sh.j2
dest: /opt/backups/scripts/backup-system.sh
mode: '0755'
- name: Create backup cron jobs
ansible.builtin.cron:
name: "{{ item.name }}"
job: "{{ item.job }}"
minute: "{{ item.minute }}"
hour: "{{ item.hour }}"
day: "{{ item.day | default('*') }}"
user: root
loop:
- name: "Daily home backup"
job: "/opt/backups/scripts/backup-home.sh >> /var/log/backups/home.log 2>&1"
minute: "0"
hour: "2"
- name: "Daily system config backup"
job: "/opt/backups/scripts/backup-system.sh >> /var/log/backups/system.log 2>&1"
minute: "30"
hour: "2"
when: backup_enable_cron | default(true) | bool

View File

@ -0,0 +1,31 @@
#!/bin/bash
# Home directory backup script
# Generated by Ansible
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/opt/backups/home"
LOG_FILE="/var/log/backups/home.log"
echo "$(date): Starting home backup" >> "$LOG_FILE"
# Create backup directory
mkdir -p "$BACKUP_DIR"
# Backup each user's home directory
{% for user in backup_users | default(['master', 'beast', 'ladmin', 'user']) %}
if [ -d "/home/{{ user }}" ]; then
echo "$(date): Backing up /home/{{ user }}" >> "$LOG_FILE"
rsync -av --delete \
--exclude='.cache' \
--exclude='.local/share/Trash' \
--exclude='snap' \
--exclude='.docker' \
/home/{{ user }}/ \
"$BACKUP_DIR/{{ user }}_$DATE/" >> "$LOG_FILE" 2>&1
fi
{% endfor %}
# Keep only last 7 days of backups
find "$BACKUP_DIR" -type d -name "*_20*" -mtime +7 -exec rm -rf {} \; 2>/dev/null
echo "$(date): Home backup completed" >> "$LOG_FILE"

View File

@ -0,0 +1,43 @@
#!/bin/bash
# System configuration backup script
# Generated by Ansible
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/opt/backups/system"
LOG_FILE="/var/log/backups/system.log"
echo "$(date): Starting system backup" >> "$LOG_FILE"
# Create backup directory
mkdir -p "$BACKUP_DIR/$DATE"
# Backup important system directories
for dir in /etc /var/lib/dpkg /var/lib/apt/extended_states; do
if [ -d "$dir" ]; then
echo "$(date): Backing up $dir" >> "$LOG_FILE"
rsync -av "$dir" "$BACKUP_DIR/$DATE/" >> "$LOG_FILE" 2>&1
fi
done
# Backup crontabs
if [ -d /var/spool/cron/crontabs ]; then
cp -r /var/spool/cron/crontabs "$BACKUP_DIR/$DATE/"
fi
# Create system info snapshot
{
echo "=== System Info ==="
uname -a
lsb_release -a 2>/dev/null
echo ""
echo "=== Installed Packages ==="
dpkg --get-selections
echo ""
echo "=== Services ==="
systemctl list-unit-files --type=service --state=enabled
} > "$BACKUP_DIR/$DATE/system-info.txt"
# Keep only last 30 days of system backups
find "$BACKUP_DIR" -type d -name "20*" -mtime +30 -exec rm -rf {} \; 2>/dev/null
echo "$(date): System backup completed" >> "$LOG_FILE"

View File

@ -1,11 +1,6 @@
---
# handlers file for base
- name: Restart fail2ban
ansible.builtin.systemd:
name: fail2ban
state: restarted
- name: Reload ufw
ansible.builtin.command: ufw reload
changed_when: false

View File

@ -1 +0,0 @@
dependencies: []

View File

@ -11,12 +11,7 @@
# Network and admin tools
- net-tools
- ufw
- fail2ban
- mailutils
# Monitoring tools
- iotop
- nethogs
- logwatch
# Modern CLI tools
- jq
- ripgrep
@ -27,7 +22,6 @@
community.general.snap:
name:
- yq
- btop
state: present
- name: Create fd symlink (Ubuntu uses fd-find)
@ -37,12 +31,7 @@
state: link
when: ansible_distribution == "Ubuntu"
- name: Configure fail2ban
ansible.builtin.template:
src: jail.local.j2
dest: /etc/fail2ban/jail.local
mode: '0644'
notify: restart fail2ban
# fail2ban configuration moved to monitoring role
# UFW enablement moved to ssh role to avoid lockout

View File

@ -1,52 +0,0 @@
galaxy_info:
author: ansible-user
description: Development tools and environment setup role
company: Personal
# If the issue tracker for your role is not on github, uncomment the
# next line and provide a value
# issue_tracker_url: http://example.com/issue/tracker
# Choose a valid license ID from https://spdx.org - some suggested licenses:
# - BSD-3-Clause (default)
# - MIT
# - GPL-2.0-or-later
# - GPL-3.0-only
# - Apache-2.0
# - CC-BY-4.0
license: MIT
min_ansible_version: "2.9"
# If this a Container Enabled role, provide the minimum Ansible Container version.
# min_ansible_container_version:
#
# Provide a list of supported platforms, and for each platform a list of versions.
# If you don't wish to enumerate all versions for a particular platform, use 'all'.
# To view available platforms and versions (or releases), visit:
# https://galaxy.ansible.com/api/v1/platforms/
#
# platforms:
# - name: Fedora
# versions:
# - all
# - 25
# - name: SomePlatform
# versions:
# - all
# - 1.0
# - 7
# - 99.99
galaxy_tags: []
# List tags for your role here, one per line. A tag is a keyword that describes
# and categorizes the role. Users find roles by searching for tags. Be sure to
# remove the '[]' above, if you add tags to this list.
#
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
# Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
# if you add dependencies to this list.

View File

@ -1,52 +0,0 @@
galaxy_info:
author: ansible-user
description: Docker installation and configuration role
company: Personal
# If the issue tracker for your role is not on github, uncomment the
# next line and provide a value
# issue_tracker_url: http://example.com/issue/tracker
# Choose a valid license ID from https://spdx.org - some suggested licenses:
# - BSD-3-Clause (default)
# - MIT
# - GPL-2.0-or-later
# - GPL-3.0-only
# - Apache-2.0
# - CC-BY-4.0
license: MIT
min_ansible_version: "2.9"
# If this a Container Enabled role, provide the minimum Ansible Container version.
# min_ansible_container_version:
#
# Provide a list of supported platforms, and for each platform a list of versions.
# If you don't wish to enumerate all versions for a particular platform, use 'all'.
# To view available platforms and versions (or releases), visit:
# https://galaxy.ansible.com/api/v1/platforms/
#
# platforms:
# - name: Fedora
# versions:
# - all
# - 25
# - name: SomePlatform
# versions:
# - all
# - 1.0
# - 7
# - 99.99
galaxy_tags: []
# List tags for your role here, one per line. A tag is a keyword that describes
# and categorizes the role. Users find roles by searching for tags. Be sure to
# remove the '[]' above, if you add tags to this list.
#
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
# Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
# if you add dependencies to this list.

View File

@ -3,13 +3,29 @@
# Package management settings
maintenance_update_cache: true # Update apt cache before operations
maintenance_upgrade_packages: true # Perform dist-upgrade
maintenance_upgrade_packages: true # Perform package upgrades
maintenance_upgrade_type: "safe" # safe, full, or dist (safe is more reliable)
maintenance_autoremove: true # Remove unused packages
maintenance_autoclean: true # Clean apt cache
maintenance_fix_broken: true # Fix broken packages before upgrade
# Network resilience settings
maintenance_apt_retries: 3 # Number of retries for apt operations
maintenance_apt_retry_delay: 30 # Delay between retries (seconds)
maintenance_cache_retry_delay: 10 # Delay between cache update retries
maintenance_individual_upgrade_fallback: true # Try individual upgrades if bulk fails
# Timeout settings
maintenance_bulk_upgrade_timeout: 1800 # 30 minutes for bulk upgrade
maintenance_individual_timeout: 600 # 10 minutes per individual package
maintenance_bulk_poll_interval: 30 # Check bulk progress every 30s
maintenance_individual_poll_interval: 15 # Check individual progress every 15s
# Reboot handling settings
maintenance_check_reboot: true # Check if reboot is required
maintenance_allow_reboot: true # Allow automatic reboots
maintenance_reboot_timeout: 300 # Reboot timeout in seconds
maintenance_pre_reboot_delay: 5 # Delay before reboot in seconds
# Cache settings
maintenance_cache_valid_time: 3600 # Cache valid time in seconds (1 hour)

View File

@ -1,52 +0,0 @@
galaxy_info:
author: ansible-user
description: System maintenance and updates role
company: Personal
# If the issue tracker for your role is not on github, uncomment the
# next line and provide a value
# issue_tracker_url: http://example.com/issue/tracker
# Choose a valid license ID from https://spdx.org - some suggested licenses:
# - BSD-3-Clause (default)
# - MIT
# - GPL-2.0-or-later
# - GPL-3.0-only
# - Apache-2.0
# - CC-BY-4.0
license: MIT
min_ansible_version: "2.9"
# If this a Container Enabled role, provide the minimum Ansible Container version.
# min_ansible_container_version:
#
# Provide a list of supported platforms, and for each platform a list of versions.
# If you don't wish to enumerate all versions for a particular platform, use 'all'.
# To view available platforms and versions (or releases), visit:
# https://galaxy.ansible.com/api/v1/platforms/
#
# platforms:
# - name: Fedora
# versions:
# - all
# - 25
# - name: SomePlatform
# versions:
# - all
# - 1.0
# - 7
# - 99.99
galaxy_tags: []
# List tags for your role here, one per line. A tag is a keyword that describes
# and categorizes the role. Users find roles by searching for tags. Be sure to
# remove the '[]' above, if you add tags to this list.
#
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
# Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
# if you add dependencies to this list.

View File

@ -1,27 +1,169 @@
---
- name: Upgrade all packages
- name: Get list of upgradable packages (for reporting)
ansible.builtin.shell: |
apt list --upgradable 2>/dev/null | grep -v "WARNING" | tail -n +2 | wc -l
args:
executable: /bin/bash
register: maintenance_upgradable_count
changed_when: false
- name: Display packages to be upgraded
ansible.builtin.debug:
msg: |
📦 Package Upgrade Summary:
- Total packages to upgrade: {{ maintenance_upgradable_count.stdout | default('0') }}
- Upgrade type: {{ maintenance_upgrade_type }}
- Max retries: {{ maintenance_apt_retries }}
- Retry delay: {{ maintenance_apt_retry_delay }}s
when: ansible_debug_output | default(false) | bool
- name: Show upgradable packages (first 10)
ansible.builtin.shell: |
apt list --upgradable 2>/dev/null | grep -v "WARNING" | head -10
args:
executable: /bin/bash
register: maintenance_upgradable_packages_preview
changed_when: false
when: maintenance_upgradable_count.stdout | int > 0
- name: Display upgradable packages
ansible.builtin.debug:
msg: |
📋 Packages to upgrade:
{{ maintenance_upgradable_packages_preview.stdout_lines | join('\n') }}
when:
- maintenance_upgradable_count.stdout | int > 0
- ansible_debug_output | default(false) | bool
- maintenance_upgradable_packages_preview.stdout_lines is defined
- name: Update apt cache with retries
ansible.builtin.apt:
upgrade: dist
update_cache: "{{ maintenance_update_cache }}"
cache_valid_time: "{{ maintenance_cache_valid_time }}"
retries: "{{ maintenance_apt_retries }}"
delay: "{{ maintenance_cache_retry_delay }}"
register: maintenance_apt_update_result
until: maintenance_apt_update_result is succeeded
when: maintenance_update_cache | bool
- name: Fix broken packages if any
ansible.builtin.command:
cmd: apt-get --fix-broken install -y # noqa command-instead-of-module
become: true
changed_when: false
failed_when: false
when: maintenance_fix_broken | bool
- name: Upgrade packages with retries and verbose output
ansible.builtin.apt:
upgrade: "{{ maintenance_upgrade_type }}"
force_apt_get: true
update_cache: false # Already updated above
environment:
DEBIAN_FRONTEND: noninteractive
APT_LISTCHANGES_FRONTEND: none
retries: "{{ maintenance_apt_retries }}"
delay: "{{ maintenance_apt_retry_delay }}"
register: maintenance_apt_upgrade_result
until: maintenance_apt_upgrade_result is succeeded
ignore_errors: true
async: "{{ maintenance_bulk_upgrade_timeout }}"
poll: "{{ maintenance_bulk_poll_interval }}"
no_log: "{{ not (ansible_debug_output | default(false) | bool) }}"
when: maintenance_upgrade_packages | bool
- name: Fallback to individual package upgrades if full upgrade failed
when:
- maintenance_apt_upgrade_result is failed
- maintenance_individual_upgrade_fallback | bool
block:
- name: Display fallback message
ansible.builtin.debug:
msg: |
⚠️ Bulk upgrade failed, trying individual package upgrades...
This may take longer but is more reliable for problematic packages.
- name: Get list of upgradable packages for individual upgrade
ansible.builtin.shell: |
apt list --upgradable 2>/dev/null | grep -v "WARNING" | tail -n +2 | cut -d'/' -f1
args:
executable: /bin/bash
register: maintenance_upgradable_packages_fallback
changed_when: false
- name: Display packages for individual upgrade
ansible.builtin.debug:
msg: |
🔄 Attempting individual upgrade for {{ maintenance_upgradable_packages_fallback.stdout_lines | length }} packages:
{{ maintenance_upgradable_packages_fallback.stdout_lines | join(', ') }}
when: maintenance_upgradable_packages_fallback.stdout_lines | length > 0
- name: Upgrade packages individually with progress
ansible.builtin.apt:
name: "{{ item }}"
state: latest # noqa package-latest - This is intentional for maintenance upgrades
force_apt_get: true
environment:
DEBIAN_FRONTEND: noninteractive
APT_LISTCHANGES_FRONTEND: none
loop: "{{ maintenance_upgradable_packages_fallback.stdout_lines | default([]) }}"
loop_control:
label: "📦 Upgrading {{ item }} ({{ ansible_loop.index }}/{{ ansible_loop.length }})"
retries: 2
delay: 10
ignore_errors: true
async: "{{ maintenance_individual_timeout }}"
poll: "{{ maintenance_individual_poll_interval }}"
no_log: "{{ not (ansible_debug_output | default(false) | bool) }}"
register: maintenance_individual_upgrade_results
when: maintenance_upgradable_packages_fallback.stdout_lines | length > 0
- name: Summary of individual upgrades
ansible.builtin.debug:
msg: |
📊 Individual Upgrade Results:
- Total attempted: {{ maintenance_individual_upgrade_results.results | length | default(0) }}
- Successful: {{ maintenance_individual_upgrade_results.results | selectattr('changed', 'equalto', true) | list | length | default(0) }}
- Failed: {{ maintenance_individual_upgrade_results.results | selectattr('failed', 'equalto', true) | list | length | default(0) }}
when:
- maintenance_individual_upgrade_results is defined
- maintenance_individual_upgrade_results.results is defined
- name: Autoremove unused packages
ansible.builtin.apt:
autoremove: true
purge: true
retries: 2
delay: 5
when: maintenance_autoremove | bool
- name: Clean apt cache
ansible.builtin.apt:
autoclean: true
when: maintenance_autoclean | bool
- name: Check if reboot is required
ansible.builtin.stat:
path: /var/run/reboot-required
register: maintenance_reboot_required
when: maintenance_check_reboot | bool
- name: Display maintenance summary
ansible.builtin.debug:
msg: |
Maintenance Summary:
- Cache update: {{ 'Completed' if maintenance_apt_update_result is succeeded else 'Skipped/Failed' }}
- Package upgrade: {{ 'Completed' if maintenance_apt_upgrade_result is succeeded else 'Failed (fallback may have run)' }}
- Reboot required: {{ 'Yes' if (maintenance_reboot_required.stat.exists | default(false)) else 'No' }}
when: ansible_debug_output | default(false) | bool
- name: Reboot if required
ansible.builtin.reboot:
msg: "Reboot triggered by Ansible after system changes."
reboot_timeout: "{{ maintenance_reboot_timeout | default(300) }}"
pre_reboot_delay: "{{ maintenance_pre_reboot_delay | default(5) }}"
msg: "Reboot triggered by Ansible after system maintenance."
reboot_timeout: "{{ maintenance_reboot_timeout }}"
pre_reboot_delay: "{{ maintenance_pre_reboot_delay }}"
when:
- ansible_facts['pkg_mgr'] == "apt"
- maintenance_reboot_required.stat.exists
- maintenance_check_reboot | bool
- maintenance_allow_reboot | bool
- maintenance_reboot_required.stat.exists | default(false)
- not (skip_reboot | default(false) | bool)

View File

@ -0,0 +1,5 @@
---
# Monitoring role defaults
monitoring_install_snap_tools: true
monitoring_enable_sysstat: true
monitoring_create_scripts: true

View File

@ -0,0 +1,11 @@
---
- name: restart fail2ban
ansible.builtin.systemd:
name: fail2ban
state: restarted
- name: restart sysstat
ansible.builtin.systemd:
name: sysstat
state: restarted
enabled: true

View File

@ -0,0 +1,97 @@
---
- name: Install monitoring packages
ansible.builtin.apt:
name:
# System monitoring
- htop
- iotop
- nethogs
- iftop
- ncdu
- dstat
# Log monitoring
- logwatch
- fail2ban
# Network monitoring
- nmap
- tcpdump
- wireshark-common
# Performance monitoring
- sysstat
- atop
state: present
- name: Install modern monitoring tools via snap
community.general.snap:
name:
- btop
- bandwhich
state: present
- name: Configure fail2ban
ansible.builtin.template:
src: jail.local.j2
dest: /etc/fail2ban/jail.local
mode: '0644'
notify: restart fail2ban
- name: Enable sysstat data collection
ansible.builtin.lineinfile:
path: /etc/default/sysstat
regexp: '^ENABLED='
line: 'ENABLED="true"'
notify: restart sysstat
- name: Create monitoring scripts directory
ansible.builtin.file:
path: /usr/local/bin/monitoring
state: directory
mode: '0755'
- name: Deploy system monitoring script
ansible.builtin.copy:
content: |
#!/bin/bash
# System monitoring dashboard
echo "=== System Overview ==="
echo "Hostname: $(hostname)"
echo "Uptime: $(uptime -p)"
echo "Load: $(uptime | awk -F'load average:' '{print $2}')"
echo ""
echo "=== Memory ==="
free -h
echo ""
echo "=== Disk Usage ==="
df -h / /home 2>/dev/null | grep -v tmpfs
echo ""
echo "=== Top Processes ==="
ps aux --sort=-%cpu | head -6
echo ""
echo "=== Network Connections ==="
ss -tuln | head -10
echo ""
if command -v tailscale >/dev/null; then
echo "=== Tailscale Status ==="
tailscale status --peers=false 2>/dev/null || echo "Not connected"
fi
dest: /usr/local/bin/monitoring/sysinfo
mode: '0755'
- name: Deploy network monitoring script
ansible.builtin.copy:
content: |
#!/bin/bash
# Network monitoring script
echo "=== Network Interface Status ==="
ip addr show | grep -E "(inet |state )" | grep -v 127.0.0.1
echo ""
echo "=== Route Table ==="
ip route show
echo ""
echo "=== DNS Configuration ==="
cat /etc/resolv.conf | grep nameserver
echo ""
echo "=== Open Ports ==="
ss -tuln | grep LISTEN | sort
dest: /usr/local/bin/monitoring/netinfo
mode: '0755'

View File

@ -0,0 +1,33 @@
[DEFAULT]
# Ban hosts for 1 hour
bantime = 3600
# Check for repeated failures for 10 minutes
findtime = 600
# Allow 3 failures before banning
maxretry = 3
# Email notifications (uncomment and configure if needed)
destemail = idobkin@gmail.com
sender = idobkin@gmail.com
action = %(action_mwl)s
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
[apache]
enabled = false
port = http,https
filter = apache-auth
logpath = /var/log/apache2/error.log
maxretry = 3
[nginx-http-auth]
enabled = false
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 3

View File

@ -0,0 +1,27 @@
---
# Proxmox VM defaults based on your current setup
vm_name: "ansible-control"
vm_id: 110
vm_memory: 8192 # 8GB (match current successful setup)
vm_cores: 2 # 2 cores (perfect for Ansible)
vm_sockets: 1
vm_disk_size: 20G # Increase from current 6.1GB
vm_storage: "local-lvm"
vm_network_bridge: "vmbr0"
vm_os_type: "l26" # Linux 2.6+ kernel
# Ubuntu Server ISO
vm_iso: "ubuntu-24.04-live-server-amd64.iso"
vm_iso_storage: "local"
# Cloud-init settings
vm_ciuser: "master"
vm_cipassword: "" # Set in vault: vault_vm_cipassword
vm_ssh_keys: [] # Add SSH public keys
vm_ip_config: "dhcp" # or "192.168.1.100/24,gw=192.168.1.1"
vm_nameservers: "8.8.8.8 8.8.4.4"
# VM behavior
vm_start_after_create: true
vm_enable_agent: true
vm_boot_order: "order=scsi0"

View File

@ -0,0 +1,77 @@
---
# Break down the Proxmox VM creation to avoid "file name too long" error
- name: Set VM configuration facts
ansible.builtin.set_fact:
vm_scsi_config:
scsi0: "{{ vm_storage }}:{{ vm_disk_size }},format=raw"
vm_net_config:
net0: "virtio,bridge={{ vm_network_bridge }},firewall=1"
vm_ide_config:
ide2: "{{ vm_iso_storage }}:cloudinit,format=qcow2"
vm_ipconfig:
ipconfig0: "{{ vm_ip_config }}"
- name: Create VM on Proxmox
community.general.proxmox_kvm:
# Connection
api_host: "{{ proxmox_host }}"
api_user: "{{ proxmox_user }}"
api_password: "{{ vault_proxmox_password }}"
api_token_id: "{{ proxmox_token_id | default(omit) }}"
api_token_secret: "{{ vault_proxmox_token | default(omit) }}"
# VM identification
vmid: "{{ vm_id }}"
name: "{{ vm_name }}"
node: "{{ proxmox_node }}"
# Hardware specs
memory: "{{ vm_memory }}"
cores: "{{ vm_cores }}"
sockets: "{{ vm_sockets }}"
cpu: "host"
# Storage and network
scsi: "{{ vm_scsi_config }}"
net: "{{ vm_net_config }}"
ide: "{{ vm_ide_config }}"
# Boot and OS
boot: "{{ vm_boot_order }}"
ostype: "{{ vm_os_type }}"
# Cloud-init
ciuser: "{{ vm_ciuser }}"
cipassword: "{{ vault_vm_cipassword | default(omit) }}"
sshkeys: "{{ vm_ssh_keys | join('\n') if vm_ssh_keys else omit }}"
ipconfig: "{{ vm_ipconfig }}"
nameserver: "{{ vm_nameservers }}"
# VM options
agent: "{{ vm_enable_agent | bool }}"
autostart: false
balloon: 0
state: present
register: vm_creation_result
- name: Start VM if requested
community.general.proxmox_kvm:
api_host: "{{ proxmox_host }}"
api_user: "{{ proxmox_user }}"
api_password: "{{ vault_proxmox_password }}"
api_token_id: "{{ proxmox_token_id | default(omit) }}"
api_token_secret: "{{ vault_proxmox_token | default(omit) }}"
vmid: "{{ vm_id }}"
node: "{{ proxmox_node }}"
state: started
when: vm_start_after_create | bool
- name: Display VM creation results
ansible.builtin.debug:
msg: |
VM Created: {{ vm_name }} (ID: {{ vm_id }})
Memory: {{ vm_memory }}MB
Cores: {{ vm_cores }}
Storage: {{ vm_storage }}:{{ vm_disk_size }}
Network: {{ vm_network_bridge }}
Status: {{ vm_creation_result.msg | default('Created') }}

View File

@ -1,3 +1,5 @@
typeset -g POWERLEVEL9K_INSTANT_PROMPT=quiet
# Enable Powerlevel10k instant prompt. Should stay close to the top of ~/.zshrc.
# Initialization code that may require console input (password prompts, [y/n]
# confirmations, etc.) must go above this block; everything else may go below.
@ -112,3 +114,64 @@ source $ZSH/oh-my-zsh.sh
# To customize prompt, run `p10k configure` or edit ~/.p10k.zsh.
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh
[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh
alias reload="source ~/.zshrc && echo 'ZSH config reloaded from ~/.zshrc'"
alias editrc="nano ~/.zshrc"
alias c="clear"
alias ls="ls --color=auto"
alias ..="cd .."
alias ...="cd ../.."
alias ....="cd ../../.."
alias cd..="cd .."
alias h="cd ~"
alias dc="cd ~/Documents/code"
# System information
alias df="df -h" # disk usage human readable
alias du="du -h" # directory usage human readable
alias free="free -h" # memory usage human readable
# Process management
alias ps="ps aux"
alias cpu="lscpu"
alias top="btop"
alias mem="free -m"
alias ports="ss -tulpn" # open ports
# Network information
alias myip="curl -s http://ipecho.net/plain; echo"
alias localip="ip route get 1.2.3.4 | awk '{print $7}'"
# Python
alias py="python3"
alias pip="pip3"
alias venv="python3 -m venv"
alias activate="source venv/bin/activate"
# Docker
alias d="docker"
alias dc="docker-compose"
alias dcu="docker-compose up -d"
alias dcd="docker-compose down"
alias dcb="docker-compose build"
alias dps="docker ps"
alias di="docker images"
# Date and time
alias now="date +'%Y-%m-%d %H:%M:%S'"
alias today="date +'%Y-%m-%d'"
# Package management (Debian/Ubuntu)
alias update="sudo apt update && sudo apt upgrade -y"
alias install="sudo apt install"
alias remove="sudo apt remove"
alias search="apt search"
# Permissions and ownership
alias chmox="chmod +x"
alias own="sudo chown -R $USER:$USER"
alias nfresh="rm -rf node_modules/ package-lock.json && npm install"

View File

@ -1,52 +0,0 @@
galaxy_info:
author: ansible-user
description: Shell configuration and setup role
company: Personal
# If the issue tracker for your role is not on github, uncomment the
# next line and provide a value
# issue_tracker_url: http://example.com/issue/tracker
# Choose a valid license ID from https://spdx.org - some suggested licenses:
# - BSD-3-Clause (default)
# - MIT
# - GPL-2.0-or-later
# - GPL-3.0-only
# - Apache-2.0
# - CC-BY-4.0
license: MIT
min_ansible_version: "2.9"
# If this a Container Enabled role, provide the minimum Ansible Container version.
# min_ansible_container_version:
#
# Provide a list of supported platforms, and for each platform a list of versions.
# If you don't wish to enumerate all versions for a particular platform, use 'all'.
# To view available platforms and versions (or releases), visit:
# https://galaxy.ansible.com/api/v1/platforms/
#
# platforms:
# - name: Fedora
# versions:
# - all
# - 25
# - name: SomePlatform
# versions:
# - all
# - 1.0
# - 7
# - 99.99
galaxy_tags: []
# List tags for your role here, one per line. A tag is a keyword that describes
# and categorizes the role. Users find roles by searching for tags. Be sure to
# remove the '[]' above, if you add tags to this list.
#
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
# Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
# if you add dependencies to this list.

View File

@ -8,8 +8,22 @@
name:
- zsh
- tmux
- fzf
state: present
- name: Install zsh plugins
ansible.builtin.git:
repo: "{{ item.repo }}"
dest: "/home/{{ shell_target_user }}/.oh-my-zsh/custom/plugins/{{ item.name }}"
version: master
depth: 1
update: false
become: true
become_user: "{{ shell_target_user }}"
loop:
- { name: "zsh-syntax-highlighting", repo: "https://github.com/zsh-users/zsh-syntax-highlighting.git" }
- { name: "zsh-autosuggestions", repo: "https://github.com/zsh-users/zsh-autosuggestions.git" }
- name: Set zsh as default shell for user
ansible.builtin.user:
name: "{{ shell_target_user }}"

View File

@ -1,12 +0,0 @@
galaxy_info:
author: ansible-user
description: Snap package manager configuration role
company: Personal
license: MIT
min_ansible_version: "2.9"
galaxy_tags: []
dependencies: []

View File

@ -1,52 +0,0 @@
galaxy_info:
author: ansible-user
description: SSH configuration and security role
company: Personal
# If the issue tracker for your role is not on github, uncomment the
# next line and provide a value
# issue_tracker_url: http://example.com/issue/tracker
# Choose a valid license ID from https://spdx.org - some suggested licenses:
# - BSD-3-Clause (default)
# - MIT
# - GPL-2.0-or-later
# - GPL-3.0-only
# - Apache-2.0
# - CC-BY-4.0
license: MIT
min_ansible_version: "2.9"
# If this a Container Enabled role, provide the minimum Ansible Container version.
# min_ansible_container_version:
#
# Provide a list of supported platforms, and for each platform a list of versions.
# If you don't wish to enumerate all versions for a particular platform, use 'all'.
# To view available platforms and versions (or releases), visit:
# https://galaxy.ansible.com/api/v1/platforms/
#
# platforms:
# - name: Fedora
# versions:
# - all
# - 25
# - name: SomePlatform
# versions:
# - all
# - 1.0
# - 7
# - 99.99
galaxy_tags: []
# List tags for your role here, one per line. A tag is a keyword that describes
# and categorizes the role. Users find roles by searching for tags. Be sure to
# remove the '[]' above, if you add tags to this list.
#
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
# Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
# if you add dependencies to this list.

View File

@ -17,4 +17,4 @@ tailscale_reset: false # Force reconnection (will logout first)
# ENTERPRISE OPTIONS (leave empty for personal use):
tailscale_login_server: "" # Custom control server URL
tailscale_operator: "" # Operator user for Tailscale
tailscale_operator: "" # Operator user for Tailscale

View File

@ -1,13 +1,13 @@
---
- name: start tailscaled
- name: Start tailscaled
ansible.builtin.systemd:
name: tailscaled
state: started
enabled: true
become: true
- name: restart tailscaled
- name: Restart tailscaled
ansible.builtin.systemd:
name: tailscaled
state: restarted
become: true
become: true

View File

@ -1,6 +1,6 @@
---
- name: Install required packages for Alpine
ansible.builtin.apk:
community.general.apk:
name:
- curl
- gnupg
@ -22,20 +22,20 @@
become: true
- name: Update apk cache
ansible.builtin.apk:
community.general.apk:
update_cache: true
become: true
- name: Install Tailscale
ansible.builtin.apk:
community.general.apk:
name: tailscale
state: present
become: true
notify: start tailscaled
notify: Start tailscaled
- name: Enable and start Tailscale daemon
ansible.builtin.service:
name: tailscaled
enabled: true
state: started
become: true
become: true

View File

@ -7,12 +7,15 @@
become: true
- name: Determine repository codename
set_fact:
ansible.builtin.set_fact:
tailscale_repo_codename: "{{ 'jammy' if ansible_distribution == 'Ubuntu' else 'bookworm' }}"
- name: Add Tailscale repository
ansible.builtin.apt_repository:
repo: "deb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg] https://pkgs.tailscale.com/stable/{{ 'ubuntu' if ansible_distribution == 'Ubuntu' else 'debian' }} {{ tailscale_repo_codename }} main"
repo: >-
deb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg]
https://pkgs.tailscale.com/stable/{{ 'ubuntu' if ansible_distribution == 'Ubuntu' else 'debian' }}
{{ tailscale_repo_codename }} main
state: present
filename: tailscale
become: true
@ -27,11 +30,11 @@
name: tailscale
state: present
become: true
notify: start tailscaled
notify: Start tailscaled
- name: Enable and start Tailscale daemon
ansible.builtin.systemd:
name: tailscaled
enabled: true
state: started
become: true
become: true

View File

@ -1,31 +1,32 @@
---
- name: Include OS-specific installation tasks
include_tasks: "{{ ansible_os_family | lower }}.yml"
ansible.builtin.include_tasks: "{{ ansible_os_family | lower }}.yml"
- name: Fail if not running on supported OS
fail:
ansible.builtin.fail:
msg: "This role only supports Ubuntu, Debian, and Alpine systems"
when: ansible_os_family not in ["Debian", "Alpine"]
- name: Check if Tailscale is already connected
command: tailscale status --json
ansible.builtin.command: tailscale status --json
register: tailscale_status
failed_when: false
changed_when: false
- name: Parse Tailscale status
set_fact:
ansible.builtin.set_fact:
tailscale_connected: "{{ (tailscale_status.stdout | from_json).BackendState == 'Running' if tailscale_status.rc == 0 else false }}"
- name: Reset Tailscale if requested
command: tailscale logout
when:
ansible.builtin.command: tailscale logout
when:
- tailscale_reset | bool
- tailscale_connected | bool
notify: restart tailscaled
notify: Restart tailscaled
changed_when: true
- name: Connect to Tailscale network
command: >
ansible.builtin.command: >
tailscale up
{{ '--auth-key=' + tailscale_auth_key if tailscale_auth_key else '' }}
{{ '--hostname=' + tailscale_hostname if tailscale_hostname else '' }}
@ -41,10 +42,10 @@
changed_when: tailscale_up_result.rc == 0
- name: Display Tailscale status
command: tailscale status
register: final_status
ansible.builtin.command: tailscale status
register: tailscale_final_status
changed_when: false
- name: Show Tailscale connection status
debug:
msg: "{{ final_status.stdout_lines }}"
ansible.builtin.debug:
msg: "{{ tailscale_final_status.stdout_lines }}"

View File

@ -1,52 +0,0 @@
galaxy_info:
author: ansible-user
description: User account management role
company: Personal
# If the issue tracker for your role is not on github, uncomment the
# next line and provide a value
# issue_tracker_url: http://example.com/issue/tracker
# Choose a valid license ID from https://spdx.org - some suggested licenses:
# - BSD-3-Clause (default)
# - MIT
# - GPL-2.0-or-later
# - GPL-3.0-only
# - Apache-2.0
# - CC-BY-4.0
license: MIT
min_ansible_version: "2.9"
# If this a Container Enabled role, provide the minimum Ansible Container version.
# min_ansible_container_version:
#
# Provide a list of supported platforms, and for each platform a list of versions.
# If you don't wish to enumerate all versions for a particular platform, use 'all'.
# To view available platforms and versions (or releases), visit:
# https://galaxy.ansible.com/api/v1/platforms/
#
# platforms:
# - name: Fedora
# versions:
# - all
# - 25
# - name: SomePlatform
# versions:
# - all
# - 1.0
# - 7
# - 99.99
galaxy_tags: []
# List tags for your role here, one per line. A tag is a keyword that describes
# and categorizes the role. Users find roles by searching for tags. Be sure to
# remove the '[]' above, if you add tags to this list.
#
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
# Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
# if you add dependencies to this list.

View File

@ -7,6 +7,7 @@
vars:
# Variables are set in group_vars/all.yml
# Override here if needed or pass via: --extra-vars "tailscale_auth_key=your_key"
tailscale_auth_key: "{{ vault_tailscale_auth_key | default('') }}"
pre_tasks:
- name: Update package cache (Debian/Ubuntu)
@ -22,10 +23,10 @@
ansible.builtin.debug:
msg: |
Tailscale has been installed and configured on {{ inventory_hostname }}.
To connect this machine to your Tailscale network:
1. If you provided an auth key, the machine should already be connected
2. If no auth key was provided, run: sudo tailscale up
3. Check status with: tailscale status
Remember to authorize the machine in your Tailscale admin console if needed.
Remember to authorize the machine in your Tailscale admin console if needed.