364 lines
9.2 KiB
Markdown
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
|