ansible/README.md

13 KiB

Ansible Development Environment Setup

This Ansible playbook automates the setup of development environments across multiple machines.

🏗️ Architecture

Host Groups

  • dev: Development machines (dev01, 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

# 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=dev01

# Run locally
make local

Prerequisites (Manual Setup)

# 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:

Create a vault password file:

# 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

# 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 dev01

# Skip reboots for specific host
ansible-playbook dev-playbook.yml --limit bottom

Selective Execution with Tags

# Security-related roles only
make security

# Development tools only
make docker
make shell

# Applications only
make apps

# Maintenance (unified system)
make maintenance                    # All hosts
make maintenance GROUP=dev         # Specific group
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

Manual Commands

# 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:

[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:

# 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

# 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:

# 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

# 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

# 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

Unified Maintenance System

The maintenance system provides a single, intelligent command for all maintenance operations:

# Basic usage
make maintenance                    # Run on all hosts
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

# 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

# Using tags with development playbook
ansible-playbook dev-playbook.yml --tags 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

# 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

make bootstrap    # Install collections
make test         # Lint + syntax check
make check        # Dry run
make apply        # Deploy to all hosts

Host-Specific Operations

make dev HOST=dev01           # Deploy to specific host
make edit-vault HOST=dev01    # Edit encrypted host variables

Maintenance and Utilities

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 with unified maintenance
├── hosts                    # Inventory file
├── dev-playbook.yml         # Main development playbook
├── local-playbook.yml       # Local machine setup
├── maintenance-playbook.yml # Dedicated maintenance playbook
├── 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