SSH config and Ansible inventory from one host database.
sshc stores your servers in a JSON database under ~/.ssh, then generates OpenSSH config and Ansible inventory from that single source of truth. Works on Linux and Windows.
- One JSON DB for all hosts (names, IPs, users, keys, groups, comments).
- DB metadata and SHA-256 integrity checksum on the hosts payload.
- Generate
sshc_ssh_configandsshc_ansible_inventory.json(or YAML). sshc status— check integrity, drift vs generated files, missing keys.sshc list— alias ofread; optional verbose metadata output.- Optional
Includein your default~/.ssh/configsossh <host>works without-F. - Safe
generate— confirms before overwriting existing artifacts (-yto skip).
pip3 install sshc --upgradeFrom source (development):
git clone https://github.com/fahadahammed/sshc.git
cd sshc
poetry install
poetry run sshc --versionRelease notes: CHANGELOG.md.
sshc init
sshc insert --name web1 --host 192.168.0.10 --user ubuntu --groups web prod
sshc generate
sshc list
sshc statusUse generated files:
ssh -F ~/.ssh/sshc_ssh_config web1
ansible -i ~/.ssh/sshc_ansible_inventory.json all --list-hostsOn Windows (PowerShell):
ssh -F $env:USERPROFILE\.ssh\sshc_ssh_config web1| Artifact | Path |
|---|---|
| Host DB | <home>/.ssh/sshc_db.json |
| SSH config (generated) | <home>/.ssh/sshc_ssh_config |
| Ansible inventory | <home>/.ssh/sshc_ansible_inventory.json |
| OpenSSH default config | <home>/.ssh/config (optional Include only) |
<home> is your user profile directory ($HOME or %USERPROFILE%).
| Command | Description |
|---|---|
init |
Create or upgrade the host DB (adds metadata to legacy files). |
insert |
Add a host (unique name; skipped if duplicate). |
update |
Change only fields you pass; insert if name is new. |
delete |
Remove a host by name. |
read / list |
Show hosts; --verbose yes includes DB metadata. |
generate |
Rebuild SSH config and Ansible inventory from the DB. |
status |
Health check; --json for automation. |
Global: sshc --version, sshc --help.
Most subcommands accept --destination, --dbfile, and generate/status also accept --configfile / --inventoryfile.
Creates { "meta": {...}, "hosts": [] }. If the file already exists as a legacy JSON array, init upgrades it in place and keeps existing hosts.
sshc initsshc insert --name myserver --host 10.0.0.5 --user deploy \
--port 22 --groups app staging --comment "staging app"Groups are space-separated. Default user is root; default key path is <home>/.ssh/id_rsa.
Rebuilds artifacts from the DB (full replace of generated content).
sshc generate
sshc generate -y
sshc generate --include-default-config
sshc generate --filetype yaml --inventoryfile ~/.ssh/sshc_ansible_inventory.yml- Confirmation: if SSH config or inventory already have content, you are prompted (
Overwrite? [y/N]:). Use-y/--yesin scripts. - Include in default SSH config:
--include-default-configadds a managed block to<home>/.ssh/configpointing atsshc_ssh_configso you can runssh <hostname>without-F. Your mainconfigis not overwritten—only anIncludeblock is added or updated. - Prefer
sshc_ssh_configover writing directly toconfigso personal SSH settings stay separate.
sshc status
sshc status --jsonExit code 0 when healthy (warnings allowed); 1 when regeneration is required or integrity fails.
sshc update --name myserver --port 2222
sshc delete --hostname myserver
sshc list --verbose yesGenerated SSH config (excerpt)
# Generated At: 2023-01-24 11:35:25.885044
# sshc Version: 3.0.0
# -- <
Host server1
HostName 192.168.0.100
Port 22
User ubuntu
IdentityFile /home/user/.ssh/id_rsa
LogLevel INFO
Compression yes
# Comment: Personal Server: ONE
# -- >Generated Ansible inventory (excerpt)
{
"all": {
"hosts": {
"server1": {
"ansible_host": "192.168.0.100",
"ansible_port": 22,
"ansible_user": "ubuntu",
"ansible_ssh_private_key_file": "/home/user/.ssh/id_rsa"
}
},
"children": {
"personal": { "hosts": { "server1": null } }
}
},
"others": {
"generated_at": "2023-01-24 11:35:25.885044",
"sshc_version": "3.0.0"
}
}- Runtime: Python 3.7+, PyYAML (installed with the package).
- Platforms: Linux and Windows for sshc itself; OpenSSH and Ansible are separate installs used to consume generated files.
Contributions are welcome—bug reports, docs, tests, and features.
- Fork the repository and create a branch from
development(notmain). - Set up locally:
poetry install, thenpoetry run python -m unittest tests/basic-function-test.py. - Change the smallest scope that fixes the issue; match existing style in
src/sshc.py. - Document user-visible behavior in
README.mdand add an entry under[Unreleased]in CHANGELOG.md. - Open a pull request to
developmentwith a clear description and how you tested (OS, commands run).
Maintainer-oriented design notes live in the Context/ directory (architecture, CLI, data model, gotchas).
- Questions or bugs: GitHub Issues
- License: MIT
Thank you for helping improve sshc.
Fahad Ahammed — DevOps enthusiast, Dhaka, Bangladesh.