Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HomeLab Ansible

Infrastructure-as-code for my homelab. Uses playbook layering, component roles, and orchestrator roles for flexible targeting (e.g., deploy only Alloy on host A; Alloy+Loki on hosts in lokihosts).

Requirements

  • Ansible >= 2.19
  • Collections
ansible-galaxy install -r collections/requirements.yml
  • Recommended tree:
.
├── ansible.cfg
├── collections/requirements.yml
├── inventories/
│   └── prod/
│       ├── hosts.yml
│       ├── group_vars/
│       └── host_vars/
├── playbooks/
│   ├── site.yml
│   ├── base.yml
│   ├── services.yml
│   ├── docker.yml
│   └── keepalived.yml
└── roles/
    ├── apt_cache/
    ├── grafana_common/         # repo + shared prereqs
    ├── grafana_alloy/
    ├── grafana_loki/
    ├── grafana_stack/          # orchestrator (select components)
    ├── docker_common/          # engine + compose
    ├── docker_app_dns/         # AdGuard + Unbound compose app
    ├── docker_stack/           # orchestrator (select apps)
    └── keepalived/

Ensure ansible.cfg includes roles_path = ./roles:./playbooks/roles:~/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles.

Inventory (example)

all:
  children:
    rpis:
      hosts:
        adguard01: { ansible_host: 192.168.10.253 }
        adguard02: { ansible_host: 192.168.10.254 }
    grafana_hosts:
      hosts:
        adguard01:
    lokihosts:
      hosts:
        log01:
    vip_dns:
      hosts:
        adguard01:
        adguard02:

inventories/lab/group_vars/grafana_hosts.yml

grafana_components: ["alloy"]   # picked up by grafana_stack

inventories/lab/group_vars/lokihosts.yml

grafana_components: ["loki"]   # picked up by grafana_stack

inventories/lab/group_vars/docker_hosts.yml

docker_apps: ["dns"]           # picked up by docker_stack

inventories/lab/group_vars/vip_dns.yml

keepalived_group: "vip_dns"
keepalived_vrid: 52
keepalived_vip: "192.168.10.252/24"
keepalived_auth_pass: "supersecret"

Playbooks

  • playbooks/site.yml: Baseline (e.g., apt cache)
  • playbooks/docker.yml: Docker engine + selected compose apps
  • playbooks/services.yml: Grafana stack (Alloy/Loki/etc.)
  • playbooks/keepalived.yml: VRRP VIP for DNS

Examples

Run baseline on a single host:

ansible-playbook -i inventories/lab/hosts.yml playbooks/base.yml --limit adguard02

Deploy Grafana layer to its group (repo + selected components):

ansible-playbook -i inventories/lab/hosts.yml playbooks/services.yml --tags grafana

Only Alloy configure step (no Loki) on current host:

ansible-playbook -i inventories/lab/hosts.yml playbooks/services.yml --tags alloy,configure --limit adguard01

Deploy Docker engine + DNS compose app:

ansible-playbook -i inventories/lab/hosts.yml playbooks/docker.yml --tags docker

Re-render DNS compose after Certbot (adds LE mount; restarts AdGuard only):

ansible-playbook -i inventories/lab/hosts.yml -l adguard01 -t configure \
  -e 'ansible_python_interpreter=/usr/bin/python3' \
  -e 'docker_app_dir=/opt/containers/dns' \
  -e 'docker_compose_file=/opt/containers/dns/compose.yml' \
  -e 'adguard_root=/opt/containers/dns/adguardhome' \
  -e 'unbound_root=/opt/containers/dns/unbound' \
  -e 'use_host_network_for_adguard=true' \
  -e 'adguard_listen_web_port=3000' \
  -e 'unbound_host_port=5335' \
  roles/docker_app_dns/tasks/render.yml

Deploy keepalived to VIP members:

ansible-playbook -i inventories/lab/hosts.yml playbooks/keepalived.yml --tags keepalived

Tagging Convention

  • Layer: base, docker, grafana, keepalived
  • Component: alloy, loki, dns, etc.
  • Step: install, configure, start, stop, `remove

Examples:

# Install phase for all Grafana components on target hosts
--tags grafana,install

# Only Loki install
--tags loki,install

# Only Docker repo setup
--tags docker:repo

Notes

  • Orchestrators (grafana_stack, docker_stack) do nothing by default. Enable components/apps per host/group with:
    • grafana_components: ["alloy", "loki"]
    • docker_apps: ["dns"]
  • Handlers restart only affected services (e.g., Alloy or AdGuard) when templates change.
  • Prefer ansible_host in inventory so peer IPs (keepalived unicast) resolve to addresses while still honoring SSH Host aliases.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages