An automation template and framework to model, provision, and securely orchestrate a fleet of Linux devices using Ansible and Tailscale within a Vagrant-managed virtual environment.
This project demonstrates how to build a zero-config, secure administrative network (Tailnet) to run Ansible playbooks against remote hosts dynamically, using Tailscale's MagicDNS and tags instead of maintaining static SSH configurations or IP addresses.
- Automated Virtual Environment: Quickly spins up a multi-node Rocky Linux environment on VirtualBox using Vagrant.
- Dynamic Tailscale Registration: Automatically joins newly provisioned nodes to your Tailscale network (Tailnet) during bootstrapping.
- Dynamic Ansible Inventory: Uses a custom Python script (ansible_tailscale_inventory.py) that queries the local Tailscale client status to automatically discover and group active nodes by OS, tags, and online state.
- Secure Provisioning: Runs Ansible playbooks directly over encrypted Tailscale tunnels using Tailscale SSH, avoiding the need for manual SSH key management.
- Pre-configured Ansible Roles:
linux_ping: For connectivity checks.linux_init: Installs base utilities (Podman, Firewalld) and configures security rules.linux_storage: Configures LVM (Logical Volume Management) dynamically.linux_homeassistant: Installs and exposes Home Assistant inside a Podman container, securely reachable via Tailnet MagicDNS.
https://console.tailscale.com/
- Click
Access controls>JSON editor(feel free to useVisual editor, but using theJSON editormakes it easier to copy/paste) - Update
tagOwners
"tagOwners": {
"tag:admins": ["autogroup:admin"],
"tag:homeassistant": ["autogroup:member"],
"tag:vagrantvms": ["autogroup:member"],
"tag:home": ["autogroup:member"],
},
- Update
ssh
"ssh": [
{
"src": ["tag:home"],
"dst": ["tag:vagrantvms"],
"users": ["autogroup:nonroot", "root"],
"action": "accept",
},
{
"src": ["tag:home"],
"dst": ["tag:home"],
"users": ["autogroup:nonroot", "root"],
"action": "accept",
},
],
- Update
nodeAttrs
"nodeAttrs": [
{
"target": ["*"],
"app": {"tailscale.com/app-connectors": []},
},
{
"target": ["*"],
"attr": ["drive:share", "drive:access"],
},
],
- Click
Settings>Keys>Generate auth key...- Description:
vagrant - Reusable:
Yes - Expiration:
90 days - Ephemeral:
Yes - Tags:
N/A
- Description:
- Copy
./secrets.rbto./.vagrant/secrets.rb(you may have to create the./.vagrantdirectory) and updateTAILSCALE_AUTHKEY- NOTE: Anything you put in
./.vagrant/secrets.rbwill NOT be checked into git because.vagrantis in.gitignore. - NOTE: Anything you put in
./secrets.rbWILL be checked into git, so be careful to place your key in the right place.
- NOTE: Anything you put in
- For Linux:
curl -fsSL https://tailscale.com/install.sh | sh sudo tailscale up \ --reset \ --force-reauth \ --advertise-exit-node \ --ssh \ --advertise-tags home - For other clients, click
Machines>Add device>Client deviceand make sure to tag the device withhome
Before starting, you must install VirtualBox and Vagrant on your machine.
The Vagrantfile is set up to use VirtualBox.
- Ubuntu/Debian:
sudo apt update sudo apt install -y virtualbox virtualbox-ext-pack
- Fedora:
sudo dnf install -y VirtualBox akmods sudo akmods sudo systemctl restart vboxdrv
- macOS:
- Intel Macs:
brew install --cask virtualbox
- Apple Silicon (M1/M2/M3): VirtualBox support is in Developer Preview and may not be stable. You may need to adapt the
Vagrantfilefor alternative providers.
- Intel Macs:
- Windows:
Or download from the VirtualBox Downloads Page.
winget install Oracle.VirtualBox
Vagrant orchestrates the creation and provisioning of the VMs.
- Ubuntu/Debian:
sudo apt update && sudo apt install -y wget gpg wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(grep -oP '(?<=UBUNTU_CODENAME=).*' /etc/os-release || lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list sudo apt update && sudo apt install -y vagrant
- Fedora:
wget -O- https://rpm.releases.hashicorp.com/fedora/hashicorp.repo | sudo tee /etc/yum.repos.d/hashicorp.repo sudo dnf -y install vagrant - RHEL/CentOS/Rocky Linux:
sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo sudo yum -y install vagrant
- macOS:
brew tap hashicorp/tap brew install hashicorp/tap/hashicorp-vagrant
- Windows:
Or download from the Vagrant Downloads Page.
winget install HashiCorp.Vagrant
Verify the installation by running:
vagrant --version- Read
Vagrantfileand update if necessary - By default, Vagrant will spin up 2 Rocky10 VMs with 2 GB memory and 2 CPUs. Be sure your computer can handle this before trying to spin them up.
- Modify
./.vagrant/secrets.rbto change the number of VMs, memory or CPUs.
- Create
vagrant up- When you're finished, make sure to destroy the VMs:
vagrant destroy -f # -f allows for no-prompt destruction- Use
ansible.shto create and activate a python3 venv, install requirements.txt, install requirements.yml, run linter, then run main.yml
## 1. create and activate a python3 venv, install requirements.txt, install requirements.yml, run linter
/bin/bash ansible.sh
## 2. do everything in example 1 plus run ansible-playbook using the `ansible_tailscale_inventory.py` inventory
/bin/bash ansible.sh main.yml
## 3. do everything in step 2 except only for tasks tagged with `ping`... View `main.yml` for more tag options.
/bin/bash ansible.sh main.yml --tags pingmolecule reset
MOLECULE_DISTRO="rockylinux10" molecule test- In your Tailscale console, pick a VM to be your home assistant and add the
homeassistanttag. - Use
ansible.shwith thehomeassistanttag to configure home assistant on your chosen VM:
/bin/bash ansible.sh --tags homeassistant- When the role finishes, it will show a debug message with the full URL to open
Home Assistant. This URL utilizes your Tailnet magic DNS and because we opened firewall in the role, you should be able to access it from any device in your Tailnet.