{"id":19891739,"url":"https://github.com/waal70/home-infra","last_synced_at":"2026-03-17T12:17:28.415Z","repository":{"id":211488232,"uuid":"729072139","full_name":"waal70/home-infra","owner":"waal70","description":"Ansible Infrastructure as a Code for my home network and infrastructure","archived":false,"fork":false,"pushed_at":"2026-03-14T17:13:21.000Z","size":594,"stargazers_count":2,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-03-15T03:45:57.982Z","etag":null,"topics":["ansible","ansible-role","debian","homelab","homelab-automation","proxmox","proxmox-ve","python3","unifi","unifi-controller","yaml"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/waal70.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"docs/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"docs/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-12-08T10:47:51.000Z","updated_at":"2026-03-14T17:13:24.000Z","dependencies_parsed_at":"2024-07-14T18:07:11.099Z","dependency_job_id":"fd962290-a4ab-4cdb-9096-756d82e81989","html_url":"https://github.com/waal70/home-infra","commit_stats":null,"previous_names":["waal70/home-infra"],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/waal70/home-infra","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/waal70%2Fhome-infra","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/waal70%2Fhome-infra/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/waal70%2Fhome-infra/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/waal70%2Fhome-infra/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/waal70","download_url":"https://codeload.github.com/waal70/home-infra/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/waal70%2Fhome-infra/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30623656,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-17T11:26:08.186Z","status":"ssl_error","status_checked_at":"2026-03-17T11:24:37.311Z","response_time":56,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ansible","ansible-role","debian","homelab","homelab-automation","proxmox","proxmox-ve","python3","unifi","unifi-controller","yaml"],"created_at":"2024-11-12T18:19:24.209Z","updated_at":"2026-03-17T12:17:28.409Z","avatar_url":"https://github.com/waal70.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# home-infra\n\nMultiple Ansible playbooks that sets up an infrastructure. Mostly based on raspberry pi's, debian (bookworm and trixie), docker and Proxmox.\n\nIt includes an inventory-plugin that uses the UniFi Network Application, but you can also use non-dynamic inventory.\n\nPlease note that as of February 2026, the repo was restructured and this README still needs to be updated\nAlso note that I am in the process of migrating from GitHub to CodeBerg.\n  \n## Pre-requisites\n  \n* Ansible control node with ansible-core available (for some nice chicken-egg there is the role ```waal70.ansible_control``` included)\n* All controlled nodes assume a standard Debian installation that was configured using preseed.cfg from the role ```waal70.tftp```\n* This set of files assumes two named users, you will need to generate SSH keypairs for both:\n  * one that is the user that ansible will run under. You may refer to this in playbooks as ```ansible_user```\n  * one that is the user a human may use to login to ansible-controlled nodes. You may refer to this in your playbooks as ```interactive_user```\n* Note that this repository handles ansible access to hosts in two ways:\n  * After bootstrapping (a freshly applied preseed.cfg) a (temporary) key for ansible is put in authorized_keys\n  * When running any playbook, this key will be replaced by a trusted CA key, authorized_keys will be nuked. You will have to connect over SSH using a signed SSH-key (signed by the appropriate CA). A helper script is included. This can also be done with the help of Hashicorp Vault.\n  * The standard lifetime of these keys is set to 10 minutes, because some of the plays will also connect later in the play\n* the ```group_vars/all.yml``` for your stage (see ```inventory/README.md```) should contain ```stage```. This string will be used as a folder when including private var-files, so make sure these files are findable in that folder.\n* this prefix should also be in all.yml, having value ```ansible_vault: \"ansible-vault/{{ stage }}\"```\n* For want of a better solution, this also requires the existence of a ```PRIVATE_REPO```. In my case it is a self-hosted git-repository. In this repository, among other things, the SSH-keys for the two named users are stored. The layout of that repository is as follows:\n\n```bash\nPRIVATE_REPO\n├── ansible-vault\n│   ├── ansible-galaxy-api-token\n│   ├── .vault_pass\n│   ├── \u003cproduction\u003e\n│   │   ├── \u003cFQ-rolename\u003e-vars.yml\n│   │   └── \u003cFQ-rolename\u003e.env\n├── homepage\n│   ├── bookmarks.yaml\n│   ├── custom.css\n│   ├── custom.js\n│   ├── docker.yaml\n│   ├── kubernetes.yaml\n│   ├── proxmox.yaml\n│   ├── services.yaml\n│   ├── settings.yaml\n│   └── widgets.yaml\n├── inventory\n│   ├── hosts_by_mac.json\n│   ├── inv_unifi.yml\n├── ssh-keys\n│   ├── \u003cansible_user\u003e\n│   │   ├── \u003cansible_user\u003e-key-install-only\n│   │   ├── \u003cansible_user\u003e-key-install-only.pub\n│   ├── \u003cinteractive_user\u003e\n│   │   ├── \u003cinteractive_user\u003e-yubi-1\n│   │   ├── \u003cinteractive_user\u003e-yubi-1.pub\n│   │   ├── \u003cinteractive_user\u003e-yubi-2\n│   │   ├── \u003cinteractive_user\u003e-yubi-2.pub\n│   │   ├── \u003cinteractive_user\u003e-yubi-3\n│   │   ├── \u003cinteractive_user\u003e-yubi-3.pub\n│   │   └── config\n```\n\n## Dealing with sensitive info\n  \n* Configure your vault password by setting it in ```.vault_pass```. Mine is stored in my private repo under ```ansible-vault```, as you can see above\n* Point to this file in your ```ansible.cfg```, by setting ```vault_password_file = .vault_pass``` in the ```[defaults]```-section, of course specifying the proper path to the private repository\n* Remember to subsequently run all commands from the directory where ansible.cfg is residing, or else it will not pick up the correct configuration\n* The command to encrypt sensitive info is: ```ansible-vault encrypt_string 'some_sensitive_value' --name 'variable_containing_sensitive_stuff'```\n* In case of a password - the \"some_sensitive_value\" should already be hashed with ```mkpasswd -m sha-512```\n\nExample:\n\n```bash\nansible-vault encrypt_string 'SuperSecretPassword' --name 'root_pass'\n```\n\nDepending on your .vault_pass, this will yield:\n\n```bash\nEncryption successful\nroot_pass: !vault |\n          $ANSIBLE_VAULT;1.1;AES256\n          38633730386435346138626532316130653339653031613233343533336135333132396165633736\n          3962643565633164303435363235326162346563313564650a323032383634396336663461623034\n          35376638303236636636616362303736653637313063353831613536386635383963636239306439\n          6665643262383639650a346435326531363964376463663639653962383932613264366430636630\n          34346639356365343462613434626261373430326566656433316435383563643762\n```\n\nThe variable definition string can be used in a yaml.\n\n* I protect my SSH-keys with a passphrase. You will need to run an agent and add the keys to that if you wish to not type the private key's passphrase all the time. I have included ```firstrun.sh``` to show you how to do it.\n\n### LUKS\n\nFor an extra layer of security in using a private repository, I also decided to only git clone the private repository into a LUKS-encrypted container. Please see ```luks/mountContainer.sh``` to see how I achieved this.\n\n## Inventory\n\nMy setup has Unifi-based networking, it is SDN-like and employs a controller. This means that central info on IP-addresses and connected clients is maintained by the Unifi controller.\nThis is why I choose to (dynamically) retrieve IP-addresses for hosts I would like to manage with Ansible from that controller. The key for that is the MAC-address. If you would like to use this as well, you may use the inventory-plugin from this repository, ```unifi_plugin.py```. This plugin requires the existence of a ```inv_unifi.yml```. An example is inside the ```inventory``` folder, but you use ```ansible.cfg``` to point to its forever home. In my case, you guessed it, it is in the private repository.\nThis file configures the settings for the Unifi-controller, such as the URLs for the API, the credentials, and the site you would like to target (in case of multiple sites). It also has an entry for ```macfile```. This should point to a JSON-file that contains the configuration, per-client, for ansible. An example is provided inside the ```inventory``` folder (```hosts_by_mac.json```). The ```inv_unifi.yml``` allows you to put this file wherever on your filesystem. May I suggest the ```inventory``` folder in your private repo?\n\nOf course, you may also specify a normal inventory file. Check the [Ansible documentation](https://docs.ansible.com/projects/ansible/devel/inventory_guide/intro_inventory.html) for more information on how to properly do that.\n\n## Roles included\n\nWell, I say \"included\" but in actual fact they reside in their own repositories. That is why, under the ```roles``` folder, you will find a ```requirements.yml```, listing all possible roles that are handled/used by this set of playbooks. You may manually install these roles by running:\n\n```bash\nansible-galaxy install -g -f -r roles/requirements.yml\n```\n\nIn the ```firstrun.sh```, however, there is a check included that will run this automatically, should the roles not have been found on your system.\n\n## Bootstrapping/Terraforming/Preseeding\n\nIn order to facilitate a known good basis to build from, these playbooks all expect a certain baseline of install. All of the hosts are expected to run Debian Linux (headless). As of writing this guide, trixie is the default version, although bookworm will also work most of the time. To ensure this baseline is there, the preseeding option of the debian-installer is used.\n\nIn the role ```waal70.tftp``` a tftp-server is brought to life, using the latest images from Debian. To it, a ```preseed.cfg``` is added, so that after initial install, all hosts end up in a more or less similar state, which is well described in the documentation.\n\n## PXE-boot\n\nTo further automate this, you should enable Network Booting or PXE Booting on the hosts that you wish to manage with Ansible. A howto is provided in the ```howtos``` folder of this repository (```tftp-HOWTO.md```)\n\n## General instructions to run the playbook\n\n```bash\n./firstrun.sh\nansible-playbook site.yml\n```\n\nUse ```--limit inventory_name``` to limit the execution to certain hosts.\nUse any of the numbered yaml-files (in ```playbooks```) to only select a portion of the roles.\n\n## TO DO\n\nFuture plans of this repository include:\n\n* Adding a CI/CD pipeline to automate some steps (running the playbook?) after changes are committed.\n* Implementing a 'pull' mechanism so that hosts are less dependent on the ansible-controller\n\n## License\n\n[GPLv3](https://www.gnu.org/licenses/gpl-3.0.html#license-text)\n  \n## Author information\n\nUnless otherwise noted, this entire repository is (c) 2023-2025 by André (waal70). [See github profile](https://github.com/waal70)\n\nPlease contact me if you need a commercial license for any of these files, including the ones in the ```roles/requirements.yml```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwaal70%2Fhome-infra","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwaal70%2Fhome-infra","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwaal70%2Fhome-infra/lists"}