Quick Start
Installation¶
Install Collection¶
Verify Installation¶
Quick Start Scenarios¶
Scenario 1: Harden SSH on New Server¶
Goal: Secure SSH daemon on a fresh server
# playbooks/harden-ssh.yml
---
- name: Harden SSH
hosts: new_servers
become: true
roles:
- jackaltx.solti_ensemble.sshd_harden
Run:
What Happens: - Restricts SSH algorithms to secure options - Configures timeouts - Generates secure keys - Filters weak DH moduli - Restarts SSH service
Scenario 2: Deploy MariaDB¶
Goal: Install database server for application
# playbooks/deploy-database.yml
---
- name: Deploy MariaDB
hosts: db_servers
become: true
vars_files:
- vars/vault.yml
roles:
- role: jackaltx.solti_ensemble.mariadb
vars:
mariadb_mysql_root_password: "{{ vault_mariadb_root }}"
mariadb_security: true
mariadb_bind_address: "127.0.0.1"
Run:
# Create encrypted vault file first
ansible-vault create vars/vault.yml
# Add: vault_mariadb_root: "your_secure_password"
ansible-playbook -i inventory.yml --ask-vault-pass playbooks/deploy-database.yml
What Happens: - Installs MariaDB server - Removes anonymous users and test database - Sets root password - Configures secure defaults - Starts service
Scenario 3: Connect Remote Host via VPN¶
Goal: Set up secure monitoring connectivity
# playbooks/setup-monitoring-vpn.yml
---
- name: Configure WireGuard Client
hosts: remote_hosts
become: true
vars_files:
- vars/vault.yml
roles:
- role: jackaltx.solti_ensemble.wireguard
vars:
wireguard_endpoint: "monitor-hub.example.com:51820"
wireguard_server_public_key: "{{ vault_wg_server_pubkey }}"
wireguard_client_address: "10.10.0.20/24"
wireguard_allowed_ips: "10.10.0.0/24"
wireguard_persistent_keepalive: 25
Run:
What Happens: - Installs WireGuard client - Generates client keys - Configures VPN connection - Starts wg-quick service - Establishes encrypted tunnel
Scenario 4: Full Stack Deployment¶
Goal: Deploy complete infrastructure stack
# playbooks/full-stack.yml
---
- name: Deploy Infrastructure Stack
hosts: app_servers
become: true
vars_files:
- vars/vault.yml
roles:
# Layer 1: Foundation
- role: jackaltx.solti_ensemble.sshd_harden
- role: jackaltx.solti_ensemble.fail2ban_config
# Layer 2: Infrastructure
- role: jackaltx.solti_ensemble.mariadb
vars:
mariadb_mysql_root_password: "{{ vault_mariadb_root }}"
mariadb_security: true
- role: jackaltx.solti_ensemble.nfs_client
vars:
nfs_shares:
- server: "nas.example.com"
remote_path: "/export/app_data"
local_path: "/mnt/nfs/app_data"
# Layer 3: Application
- role: jackaltx.solti_ensemble.gitea
vars:
gitea_db_type: mysql
gitea_db_host: "localhost"
gitea_db_password: "{{ vault_gitea_db_pass }}"
Run:
What Happens: - Hardens SSH - Configures fail2ban - Installs MariaDB - Mounts NFS storage - Deploys Gitea with database
Common Patterns¶
Pattern 1: Secure Defaults¶
Always enable security features:
roles:
- role: jackaltx.solti_ensemble.mariadb
vars:
mariadb_security: true # Remove test users/db
mariadb_bind_address: "127.0.0.1" # Localhost only
Pattern 2: Vault for Secrets¶
Never hardcode passwords:
# vars/vault.yml (encrypted with ansible-vault)
vault_mariadb_root: "secure_random_password_123"
vault_gitea_db_pass: "another_secure_password_456"
vault_wg_server_pubkey: "base64_encoded_public_key"
# playbook.yml
vars_files:
- vars/vault.yml
Pattern 3: Layered Deployment¶
Deploy in order of dependencies:
# Layer 1: Foundation
- jackaltx.solti_ensemble.sshd_harden
- jackaltx.solti_ensemble.podman
# Layer 2: Infrastructure (requires Layer 1)
- jackaltx.solti_ensemble.mariadb
# Layer 3: Applications (requires Layer 2)
- jackaltx.solti_ensemble.gitea
Pattern 4: Idempotent Operations¶
Roles are safe to re-run:
# First run: installs MariaDB
ansible-playbook deploy.yml
# Second run: checks state, makes no changes if already configured
ansible-playbook deploy.yml
# Output: "ok" instead of "changed"
Pattern 5: Tag-Based Execution¶
Run specific parts:
roles:
- role: jackaltx.solti_ensemble.mariadb
tags: ['database', 'infrastructure']
- role: jackaltx.solti_ensemble.gitea
tags: ['application', 'git']
Run only database:
Inventory Setup¶
Basic Inventory¶
# inventory.yml
all:
hosts:
server1.example.com:
ansible_user: lavender
ansible_become_password: "{{ vault_sudo_pass }}"
children:
db_servers:
hosts:
server1.example.com:
app_servers:
hosts:
server2.example.com:
Group Variables¶
# group_vars/db_servers.yml
mariadb_bind_address: "0.0.0.0"
mariadb_backup_enabled: true
# group_vars/app_servers.yml
gitea_domain: "git.example.com"
gitea_db_host: "server1.example.com"
Verification¶
Check Services¶
# SSH hardening applied
ssh user@server "sudo sshd -T | grep -E '(Ciphers|MACs|KexAlgorithms)'"
# MariaDB running
ssh user@server "sudo systemctl status mariadb"
# WireGuard connected
ssh user@server "sudo wg show"
# NFS mounted
ssh user@server "df -h | grep nfs"
Test Functionality¶
# Database connection
ssh user@server "mysql -u root -p -e 'SELECT VERSION();'"
# WireGuard connectivity
ssh user@server "ping -c 3 10.10.0.11"
# NFS write test
ssh user@server "sudo touch /mnt/nfs/test && sudo rm /mnt/nfs/test"
Troubleshooting¶
Playbook Fails: Connection Refused¶
Symptom:
Solution:
- Check SSH key added to target host
- Verify ansible_user has sudo access
- Test manual SSH connection
Playbook Fails: Permission Denied¶
Symptom:
Solution:
Add --ask-become-pass or set in inventory:
Service Won't Start¶
Symptom:
Solution:
Check service logs on target:
Role Not Found¶
Symptom:
Solution:
# Reinstall collection
ansible-galaxy collection install jackaltx.solti_ensemble --force
# Verify installation
ansible-galaxy collection list
Next Steps¶
For Simple Deployments¶
- Review individual role documentation
- Create playbooks for specific services
- Test in development environment
For Production Deployments¶
- Read "Architecture Overview"
- Plan service layers
- Set up Ansible Vault
- Review "Security Best Practices"
- Implement monitoring integration
For Testing and Validation¶
- Review "Testing Framework"
- Set up molecule testing
- Validate with verification tasks
Reference¶
Collection Documentation: - GitHub: http://github.com/jackaltx/solti_ensemble_collection - Documentation: http://docs.jackaltx.com
Role-Specific Docs: - MariaDB Role - WireGuard Role - SSHD Hardening Role - NFS Client Role - Gitea Role - And more...
SOLTI Ecosystem: - solti-monitoring: Observability stack - solti-containers: Testing infrastructure - solti-conductor: Proxmox orchestration