11 KiB
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 serverportainer: Portainer container managementhomepage: Homepage dashboardansible: Ansible control node
Roles
Core Roles
maintenance: System updates, package cleanup, and rebootsbase: Core system packages, security tools, and system hardeningdevelopment: Development tools (git, nodejs, build-essential, python3)shell: Shell configuration (zsh + oh-my-zsh + powerlevel10k)docker: Docker CE installation and user configurationssh: SSH server and firewall configurationuser: 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)
# 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)
# 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:
# 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 devVM
# Skip reboots for specific host
ansible-playbook dev-playbook.yml --limit bottom
Selective Execution with Tags
Using Makefile (Recommended)
# 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
# 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 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
# 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 secondsfail2ban_findtime: Time window for failuresfail2ban_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,npmbuild-essential,python3,python3-pip
Applications
brave-browser,libreoffice,evince,redshiftcode(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
Automatic Updates
The maintenance role handles:
- Package updates (
apt upgrade) - Unused package removal (
apt autoremove) - Cache cleanup (
apt autoclean) - Conditional reboots
Manual Maintenance
# Update only maintenance role
ansible-playbook dev-playbook.yml --tags maintenance
# Skip maintenance
ansible-playbook dev-playbook.yml --skip-tags maintenance
🐛 Troubleshooting
Common Issues
-
SSH Connection Issues
- Check
ansible.cfgSSH settings - Verify host keys and user permissions
- Check
-
Package Installation Failures
- Run with
-vfor verbose output - Check internet connectivity on target hosts
- Run with
-
Reboot Issues
- Use
skip_reboot=truefor problematic hosts - Check maintenance role handlers
- Use
-
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
- Original config backed up to
-
Modern CLI Tools Missing
- Check if snap is installed:
snap --version - For fd command: Symlink created at
/usr/local/bin/fd - Alternative: Use
fdfinddirectly on Ubuntu systems
- Check if snap is installed:
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=devVM # Deploy to specific host
make edit-vault HOST=devVM # 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
├── 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
- Test changes with
--checkfirst - Update documentation for new roles/tasks
- Use proper handlers for service restarts
- Follow existing naming conventions