9.2 KiB

Non-Proxmox Host Onboarding Playbook

Overview

The playbooks/onboarding/generic_host.yml playbook automates bootstrap for non-Proxmox hosts and supports two profiles:

  • new: full onboarding with security hardening.
  • existing: safe onboarding for pre-existing production hosts (key setup, Python, sudo, packages; skips SSH hardening).

Use existing for live systems like 10.0.0.151 (Traefik) and 10.0.0.251.

What It Does

1. Connectivity Test

  • Verifies SSH connection to target host
  • Uses raw commands (no Python required initially)
  • Provides clear error messages if connection fails

2. SSH Key Authentication

  • Creates .ssh directory with correct permissions
  • Copies your public SSH key to authorized_keys
  • Validates passwordless SSH authentication

3. Python & Prerequisites

  • Installs Python3 if not present
  • Installs python3-apt for Ansible module support
  • Gathers system facts

4. Passwordless Sudo

  • Creates sudoers configuration for your user
  • Validates sudo configuration syntax
  • Tests passwordless sudo access

5. Essential Packages

  • Updates apt cache
  • Installs essential tools (git, vim, curl, htop, etc.)

6. Basic Security

  • Disables root SSH login
  • Disables password authentication (SSH keys only)
  • Configures UFW firewall (allows SSH)

7. Final Validation

  • Tests complete passwordless authentication
  • Displays comprehensive onboarding summary

Usage

Method 1: Existing production hosts (safe profile)

ansible-playbook -i inventory/hosts.ini playbooks/onboarding/generic_host.yml \
  -e "target_host=docker_hosts" \
  -e "onboard_user=chester" \
  -e "onboarding_profile=existing" \
  -k -K

This is the recommended process for hosts that already run production workloads.

Method 2: Net-new host onboarding (full hardening)

# Onboard a single host
ansible-playbook -i inventory/hosts.ini playbooks/onboarding/generic_host.yml \
  -e "target_host=docker-01" \
  -e "onboard_user=chester" \
  -e "onboarding_profile=new" \
  -k -K

# -k: Prompt for SSH password
# -K: Prompt for sudo password

Method 3: Using Environment Variables

# Set credentials via environment
export ANSIBLE_SSH_PASS='your_password'
export ANSIBLE_BECOME_PASS='your_password'

# Run playbook
ansible-playbook -i inventory/hosts.ini playbooks/onboarding/generic_host.yml \
  -e "target_host=docker-01"

Method 4: Onboard Multiple Hosts

# Add new hosts to inventory first
# Then onboard them all at once
ansible-playbook -i inventory/hosts.ini playbooks/onboarding/generic_host.yml \
  -e "target_host=new_servers" \
  -e "onboarding_profile=existing" \
  -k -K

# Where 'new_servers' is a group in your inventory

Required Variables

Variable Description Default
target_host Host or group to onboard all
onboard_user Username for SSH/sudo chester
onboarding_profile new (harden) or existing (safe) new
onboard_password SSH and sudo password From env or prompt

Prerequisites

On Your Control Machine (jumpbox)

  • SSH key pair exists (~/.ssh/id_ed25519)
  • Ansible installed
  • Network connectivity to target host

On Target Host

  • SSH server running
  • User account with sudo privileges
  • Network connectivity from control machine

Step-by-Step First-Time Onboarding

Step 1: Add Host to Inventory

# inventory/hosts.ini
[new_hosts]
new-server ansible_host=10.0.0.252

Step 2: Test Connectivity

# Verify SSH access manually first
ssh chester@10.0.0.252

Step 3: Run Onboarding Playbook

ansible-playbook -i inventory/hosts.ini playbooks/onboarding/generic_host.yml \
  -e "target_host=new-server" \
  -e "onboard_user=chester" \
  -e "onboarding_profile=new" \
  -k -K

Step 4: Verify Passwordless Access

# Test Ansible ping without password
ansible -i inventory/hosts.ini new-server -m ping

# Test SSH without password
ssh chester@10.0.0.252 'sudo whoami'

Tag-Based Execution

Run specific sections only:

# Test connectivity only
ansible-playbook -i inventory/hosts.ini playbooks/onboarding/generic_host.yml \
  -e "target_host=docker-01" \
  --tags "connectivity" \
  -k

# Setup SSH keys only
ansible-playbook -i inventory/hosts.ini playbooks/onboarding/generic_host.yml \
  -e "target_host=docker-01" \
  --tags "ssh" \
  -k -K

# Skip security hardening
ansible-playbook -i inventory/hosts.ini playbooks/onboarding/generic_host.yml \
  -e "target_host=docker-01" \
  --skip-tags "security" \
  -k -K

Available Tags

Tag Section
connectivity Connection test
test Connection test
ssh SSH key setup
setup All setup tasks
python Python installation
prerequisites Package prerequisites
sudo Passwordless sudo
packages Essential packages
security Security hardening
hardening Security hardening
validate Final validation
summary Onboarding summary

Expected Output

PLAY [Onboard New Host to Ansible Management] ************************************

TASK [Test raw connection (no Python required)] **********************************
ok: [docker-01]

TASK [Display connection status] *************************************************
ok: [docker-01] => {
    "msg": "✅ Successfully connected to docker-01"
}

...

TASK [Display onboarding summary] ************************************************
ok: [docker-01] => {
    "msg": [
        "════════════════════════════════════════════════",
        "✅ HOST ONBOARDING COMPLETE",
        "════════════════════════════════════════════════",
        "Host: docker-01 (waldorf)",
        "IP: 10.0.0.251",
        "OS: Ubuntu 24.04",
        "Python: 3.12.3",
        "SSH Key Auth: ✅ Enabled",
        "Passwordless Sudo: ✅ Enabled",
        "Ansible User: chester",
        "════════════════════════════════════════════════"
    ]
}

Troubleshooting

SSH Connection Failed

# Test manual SSH first
ssh chester@10.0.0.252

# Check SSH service on target
ssh chester@10.0.0.252 'sudo systemctl status sshd'

# Verify firewall allows SSH
ssh chester@10.0.0.252 'sudo ufw status'

Python Installation Failed

# Manually install Python
ssh chester@10.0.0.252 'sudo apt-get update && sudo apt-get install -y python3'

Sudo Password Prompt Still Appears

# Check sudoers configuration
ssh chester@10.0.0.252 'sudo cat /etc/sudoers.d/chester'

# Verify syntax
ssh chester@10.0.0.252 'sudo visudo -c'

SSH Key Not Working After Setup

# Check authorized_keys permissions
ssh chester@10.0.0.252 'ls -la ~/.ssh/authorized_keys'

# Should be: -rw------- (600)

# Check SSH config on target
ssh chester@10.0.0.252 'sudo grep -E "PubkeyAuthentication|PasswordAuthentication" /etc/ssh/sshd_config'

Security Considerations

SSH Hardening Applied

  • Root login disabled
  • Password authentication disabled (after key setup)
  • SSH keys required for all access

Post-Onboarding Recommendations

  1. Review SSH Configuration

    ssh chester@host 'sudo sshd -T | grep -E "permit|password|pubkey"'
    
  2. Configure Firewall Rules

    # Allow only required services
    ssh chester@host 'sudo ufw allow 22/tcp && sudo ufw enable'
    
  3. Enable Automatic Security Updates

    ssh chester@host 'sudo apt-get install unattended-upgrades'
    
  4. Set Up Fail2Ban

    ssh chester@host 'sudo apt-get install fail2ban'
    

Integration with Other Playbooks

After onboarding, you can run any playbook without passwords:

# Install Docker
ansible-playbook -i inventory/hosts.ini playbooks/manage_docker_environment.yml \
  --limit new-server \
  --tags "install"

# Configure networking
ansible-playbook -i inventory/hosts.ini playbooks/baseline_network_config.yml \
  --limit new-server

Bulk Onboarding Workflow

For onboarding multiple hosts at once:

1. Create Temporary Inventory

# inventory/new-hosts.ini
[pending_onboard]
server-01 ansible_host=10.0.0.101
server-02 ansible_host=10.0.0.102
server-03 ansible_host=10.0.0.103

[pending_onboard:vars]
ansible_user=chester

2. Run Onboarding

ansible-playbook -i inventory/new-hosts.ini playbooks/onboarding/generic_host.yml \
  -e "target_host=pending_onboard" \
  -e "onboarding_profile=existing" \
  -k -K

3. Merge into Main Inventory

After successful onboarding, add hosts to your main inventory/hosts.ini file.

Next Steps

After successful onboarding:

  1. Assign to appropriate groups in inventory/hosts.ini
  2. Configure group_vars for role-specific settings
  3. Run role-specific playbooks (Docker, networking, etc.)
  4. Deploy monitoring exporter for standalone hosts
ansible-playbook -i inventory/hosts.ini playbooks/monitoring/deploy_swarm_monitoring.yml --tags docker-hosts
  1. Document host purpose in your infrastructure documentation