364 lines
9.2 KiB
Markdown

# 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)
```bash
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)
```bash
# 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
```bash
# 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
```bash
# 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
```ini
# inventory/hosts.ini
[new_hosts]
new-server ansible_host=10.0.0.252
```
### Step 2: Test Connectivity
```bash
# Verify SSH access manually first
ssh chester@10.0.0.252
```
### Step 3: Run Onboarding Playbook
```bash
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
```bash
# 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:
```bash
# 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
```bash
# 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
```bash
# Manually install Python
ssh chester@10.0.0.252 'sudo apt-get update && sudo apt-get install -y python3'
```
### Sudo Password Prompt Still Appears
```bash
# 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
```bash
# 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**
```bash
ssh chester@host 'sudo sshd -T | grep -E "permit|password|pubkey"'
```
2. **Configure Firewall Rules**
```bash
# Allow only required services
ssh chester@host 'sudo ufw allow 22/tcp && sudo ufw enable'
```
3. **Enable Automatic Security Updates**
```bash
ssh chester@host 'sudo apt-get install unattended-upgrades'
```
4. **Set Up Fail2Ban**
```bash
ssh chester@host 'sudo apt-get install fail2ban'
```
## Integration with Other Playbooks
After onboarding, you can run any playbook without passwords:
```bash
# 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
```ini
# 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
```bash
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](../../inventory/hosts.ini) file.
## Next Steps
After successful onboarding:
1. **Assign to appropriate groups** in [inventory/hosts.ini](../../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**
```bash
ansible-playbook -i inventory/hosts.ini playbooks/monitoring/deploy_swarm_monitoring.yml --tags docker-hosts
```
5. **Document host purpose** in your infrastructure documentation