# Ansible Development Environment Setup This Ansible playbook automates the setup of development environments across multiple machines. ## 🏗️ Architecture ### Host Groups - `dev`: Development machines (devVM, bottom, debianDesktopVM) - `gitea`: Gitea server - `portainer`: Portainer container management - `homepage`: Homepage dashboard - `ansible`: Ansible control node ### Roles #### Core Roles - **`maintenance`**: System updates, package cleanup, and reboots - **`base`**: Core system packages, security tools, and system hardening - **`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) ## 🚀 Usage ### Quick Start with Makefile (Recommended) ```bash # Setup dependencies make bootstrap # Test everything make test # Dry run to see what would change make check # Apply to all development hosts make apply # Run on specific host make dev HOST=devVM # Run locally make local ``` ### Prerequisites (Manual Setup) ```bash # Install required collections ansible-galaxy collection install -r collections/requirements.yml ``` ### Vault Password Setup Host variables are encrypted with Ansible Vault. You have two options: #### Option 1: Vault Password File (Recommended) Create a vault password file: ```bash # Create the vault password file echo "your_vault_password" > ~/.ansible-vault-pass chmod 600 ~/.ansible-vault-pass ``` #### Option 2: Interactive Password Prompt Use `--ask-vault-pass` with each command to be prompted for the vault password. ### Basic Setup ```bash # Run on all development machines (with vault password file) ansible-playbook dev-playbook.yml # 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 devVM # Skip reboots for specific host ansible-playbook dev-playbook.yml --limit bottom ``` ### Selective Execution with Tags #### Using Makefile (Recommended) ```bash # Security-related roles only make security # Development tools only make docker make shell # Applications only make apps # Maintenance only make maintenance # Check connectivity make status # Get detailed help make help ``` #### Manual Commands ```bash # Security-related roles only ansible-playbook dev-playbook.yml --tags security # Development tools only ansible-playbook dev-playbook.yml --tags development,docker # Applications only ansible-playbook dev-playbook.yml --tags apps # 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 devVM # Enable debug output (shows detailed status information) ansible-playbook dev-playbook.yml --limit devVM -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 ``` ## 🔧 Configuration ### Global Variables (`group_vars/all.yml`) - `timezone`: System timezone (default: UTC) - `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_maxretry`: Max failures before ban ### SSH Configuration (`roles/ssh/defaults/main.yml`) The SSH role provides 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') - `ssh_max_auth_tries`: Authentication attempts (default: 3) - `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 ## 🛡️ 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 - Modern cryptographic algorithms (ChaCha20-Poly1305, AES-256-GCM) - Secure key exchange (Curve25519, DH Group 16) - Disabled password authentication - Connection rate limiting and timeouts - User/group access restrictions - Configuration validation and automatic backup ### System Hardening - Timezone and locale configuration - Security package installation - Modern CLI tools and system monitoring ## 📦 Installed Packages ### Base System - **Core utilities**: `curl`, `wget`, `unzip`, `xclip`, `tree` - **Network/Security**: `net-tools`, `ufw`, `fail2ban`, `mailutils` - **Monitoring**: `iotop`, `nethogs`, `logwatch`, `btop` (via snap) - **Modern CLI**: `jq`, `yq` (via snap), `ripgrep`, `fd-find` ### Development Tools - `git`, `nodejs`, `npm` - `build-essential`, `python3`, `python3-pip` ### Applications - `brave-browser`, `libreoffice`, `evince`, `redshift` - `code` (VSCode), `cursor` (via snap) ### Docker - Docker CE with all components - Docker Compose - User added to docker group ## 🔧 Modern CLI Tools The base role installs modern replacements for traditional Unix tools: ### Available Commands ```bash # Fast searching rg "pattern" files/ # ripgrep - faster than grep fd "filename" # fd-find - intuitive find replacement # Data processing jq '.key' file.json # JSON processor and formatter yq '.key' file.yaml # YAML processor and formatter # System monitoring btop # Modern system monitor (better than htop) tree directory/ # Directory structure visualization # 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 ### Automatic Updates The maintenance role handles: - Package updates (`apt upgrade`) - Unused package removal (`apt autoremove`) - Cache cleanup (`apt autoclean`) - Conditional reboots ### Manual Maintenance ```bash # Update only maintenance role ansible-playbook dev-playbook.yml --tags maintenance # Skip maintenance ansible-playbook dev-playbook.yml --skip-tags maintenance ``` ## 🐛 Troubleshooting ### Common Issues 1. **SSH Connection Issues** - Check `ansible.cfg` SSH settings - Verify host keys and user permissions 2. **Package Installation Failures** - Run with `-v` for verbose output - Check internet connectivity on target hosts 3. **Reboot Issues** - Use `skip_reboot=true` for problematic hosts - Check maintenance role handlers 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 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 ### Debug Commands ```bash # Using Makefile make status # Test connectivity to all hosts make facts # Gather facts from all hosts make debug # Run with debug output make verbose # Run with verbose output # Manual commands ansible dev -m ping # Test connectivity 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 ``` ## 🛠️ Makefile Workflows The included `Makefile` provides convenient shortcuts for common operations: ### Development Workflow ```bash make bootstrap # Install collections make test # Lint + syntax check make check # Dry run make apply # Deploy to all hosts ``` ### Host-Specific Operations ```bash make dev HOST=devVM # Deploy to specific host make edit-vault HOST=devVM # Edit encrypted host variables ``` ### Maintenance and Utilities ```bash make clean # Clean up artifacts make status # Check host connectivity 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 ├── hosts # Inventory file ├── dev-playbook.yml # Main development playbook ├── local-playbook.yml # Local machine setup ├── collections/ │ └── requirements.yml # Required Ansible collections ├── group_vars/ │ └── all.yml # Global variables ├── 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 ``` ## 🤝 Contributing 1. Test changes with `--check` first 2. Update documentation for new roles/tasks 3. Use proper handlers for service restarts 4. Follow existing naming conventions