From b083301a13d897aeda9bd40220417209572853a9 Mon Sep 17 00:00:00 2001 From: UncertainMeow Date: Thu, 21 Aug 2025 15:53:57 -0400 Subject: [PATCH] feat: add docker-compose NAS playbook --- CHANGELOG.md | 6 +++ README.md | 5 ++- ansible-infrastructure/inventory/hosts.yml | 14 ++++++- .../deployment/docker-compose-nas.yml | 34 +++++++++++++++++ .../deployment/templates/dns-zone-setup.sh.j2 | 5 ++- .../roles/tailscale/defaults/main.yml | 3 +- .../roles/tailscale/tasks/configure.yml | 37 +++++++++++++------ 7 files changed, 86 insertions(+), 18 deletions(-) create mode 100644 ansible-infrastructure/playbooks/deployment/docker-compose-nas.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 869be04..a16d330 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to the HomeLab Infrastructure project will be documented in this file. +## [Unreleased] +### Added +- Tailscale role: optional DNS server configuration via `tailscale_dns_servers` +- DNS zone setup script: openwebui record and corrected htpc IP +- Playbook: `docker-compose-nas.yml` to deploy NAS stack on htpc + ## [2.0.0] - 2025-08-20 ### 🚀 Major Features Added diff --git a/README.md b/README.md index da132e0..cb87a37 100644 --- a/README.md +++ b/README.md @@ -80,9 +80,10 @@ Internal → DNS Server → Caddy → Services **Playbooks:** - **`playbooks/deployment/gitlab-stack.yml`** - Complete GitLab CE deployment with Caddy -- **`playbooks/deployment/technitium-dns-container.yml`** - DNS server deployment +- **`playbooks/deployment/technitium-dns-container.yml`** - DNS server deployment - **`playbooks/setup/initial-setup.yml`** - Server hardening and user management - **`playbooks/maintenance/hardware-assessment.yml`** - AI/ML hardware analysis +- **`playbooks/deployment/docker-compose-nas.yml`** - Deploy Docker Compose NAS stack on htpc **Roles:** - **`roles/gitlab_stack/`** - Comprehensive GitLab + Caddy + Tailscale integration @@ -331,4 +332,4 @@ MIT License - see [LICENSE](LICENSE) file for details. - **Documentation**: Comprehensive guides and examples - **Testing**: Validation framework for all components -**Built with ❤️ for homelab enthusiasts and infrastructure automation** \ No newline at end of file +**Built with ❤️ for homelab enthusiasts and infrastructure automation** diff --git a/ansible-infrastructure/inventory/hosts.yml b/ansible-infrastructure/inventory/hosts.yml index 05b9316..b4557d9 100644 --- a/ansible-infrastructure/inventory/hosts.yml +++ b/ansible-infrastructure/inventory/hosts.yml @@ -5,6 +5,8 @@ all: ansible_user: ansible ansible_python_interpreter: /usr/bin/python3 ansible_ssh_common_args: '-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null' + tailscale_dns_servers: + - 10.203.1.3 children: # Proxmox infrastructure @@ -59,6 +61,16 @@ all: ansible_become: true ansible_become_method: sudo dns_server: technitium + + # Media and storage servers + media_servers: + hosts: + htpc: + ansible_host: 10.203.3.48 + hardware_profile: media_server + vars: + ansible_become: true + ansible_become_method: sudo # Infrastructure as Code services iac_services: @@ -80,4 +92,4 @@ all: monitoring: hosts: vars: - monitoring_stack: prometheus \ No newline at end of file + monitoring_stack: prometheus diff --git a/ansible-infrastructure/playbooks/deployment/docker-compose-nas.yml b/ansible-infrastructure/playbooks/deployment/docker-compose-nas.yml new file mode 100644 index 0000000..9199eeb --- /dev/null +++ b/ansible-infrastructure/playbooks/deployment/docker-compose-nas.yml @@ -0,0 +1,34 @@ +--- +- name: Deploy Docker Compose NAS stack + hosts: htpc + become: true + vars: + nas_repo: https://github.com/AdrienPoupa/docker-compose-nas.git + nas_dir: /opt/docker-compose-nas + tasks: + - name: Ensure git is installed + ansible.builtin.apt: + name: git + state: present + update_cache: true + + - name: Clone Docker Compose NAS repository + ansible.builtin.git: + repo: "{{ nas_repo }}" + dest: "{{ nas_dir }}" + version: main + notify: Restart NAS stack + + - name: Start NAS stack + ansible.builtin.command: docker compose up -d + args: + chdir: "{{ nas_dir }}" + register: nas_up + changed_when: "'Creating' in nas_up.stdout or 'Recreating' in nas_up.stdout" + + handlers: + - name: Restart NAS stack + ansible.builtin.command: docker compose up -d + args: + chdir: "{{ nas_dir }}" + changed_when: false diff --git a/ansible-infrastructure/playbooks/deployment/templates/dns-zone-setup.sh.j2 b/ansible-infrastructure/playbooks/deployment/templates/dns-zone-setup.sh.j2 index 8c69a15..899c909 100644 --- a/ansible-infrastructure/playbooks/deployment/templates/dns-zone-setup.sh.j2 +++ b/ansible-infrastructure/playbooks/deployment/templates/dns-zone-setup.sh.j2 @@ -30,15 +30,16 @@ echo "Adding homelab host records..." call_dns_api "/zones/records/add" "domain=${DOMAIN}&name=socrates&type=A&ipAddress=10.203.3.42&ttl=300" call_dns_api "/zones/records/add" "domain=${DOMAIN}&name=rawls&type=A&ipAddress=10.203.3.47&ttl=300" call_dns_api "/zones/records/add" "domain=${DOMAIN}&name=rseau&type=A&ipAddress=10.203.1.2&ttl=300" -call_dns_api "/zones/records/add" "domain=${DOMAIN}&name=htpc&type=A&ipAddress=10.203.3.46&ttl=300" +call_dns_api "/zones/records/add" "domain=${DOMAIN}&name=htpc&type=A&ipAddress=10.203.3.48&ttl=300" call_dns_api "/zones/records/add" "domain=${DOMAIN}&name=zinn&type=A&ipAddress=10.203.3.223&ttl=300" # Services (initially pointing to rawls) call_dns_api "/zones/records/add" "domain=${DOMAIN}&name=gitlab&type=A&ipAddress=10.203.3.47&ttl=300" call_dns_api "/zones/records/add" "domain=${DOMAIN}&name=semaphore&type=A&ipAddress=10.203.3.47&ttl=300" +call_dns_api "/zones/records/add" "domain=${DOMAIN}&name=openwebui&type=A&ipAddress=10.203.3.42&ttl=300" # DNS server itself call_dns_api "/zones/records/add" "domain=${DOMAIN}&name=dns&type=A&ipAddress=10.203.1.3&ttl=300" echo "✅ DNS zone setup completed for ${DOMAIN}" -echo "🔍 You can verify at: {{ dns_admin_url }}" \ No newline at end of file +echo "🔍 You can verify at: {{ dns_admin_url }}" diff --git a/ansible-infrastructure/roles/tailscale/defaults/main.yml b/ansible-infrastructure/roles/tailscale/defaults/main.yml index eba5a8e..010c1be 100644 --- a/ansible-infrastructure/roles/tailscale/defaults/main.yml +++ b/ansible-infrastructure/roles/tailscale/defaults/main.yml @@ -10,6 +10,7 @@ tailscale_advertise_exit_node: false tailscale_advertise_routes: [] # e.g., ["10.203.0.0/16"] tailscale_accept_routes: true tailscale_accept_dns: true +tailscale_dns_servers: [] # e.g., ["10.203.1.3"] # Security settings tailscale_shields_up: false @@ -28,4 +29,4 @@ tailscale_subnet_routes: [] # e.g., ["10.203.0.0/16"] # Exit node configuration tailscale_exit_node: false -tailscale_exit_node_allow_lan_access: true \ No newline at end of file +tailscale_exit_node_allow_lan_access: true diff --git a/ansible-infrastructure/roles/tailscale/tasks/configure.yml b/ansible-infrastructure/roles/tailscale/tasks/configure.yml index 444ad21..5aa9a99 100644 --- a/ansible-infrastructure/roles/tailscale/tasks/configure.yml +++ b/ansible-infrastructure/roles/tailscale/tasks/configure.yml @@ -2,41 +2,43 @@ # Configure Tailscale settings - name: Get current Tailscale status - command: tailscale status --json + ansible.builtin.command: tailscale status --json register: tailscale_current_status failed_when: false changed_when: false - name: Parse current status - set_fact: + ansible.builtin.set_fact: current_tailscale_config: "{{ tailscale_current_status.stdout | from_json if tailscale_current_status.rc == 0 else {} }}" - name: Configure subnet routes (if specified) - command: > + ansible.builtin.command: > tailscale up --advertise-routes={{ tailscale_subnet_routes | join(',') }} {% if tailscale_accept_routes %} --accept-routes {% endif %} - when: + when: - tailscale_subnet_routes | length > 0 - current_tailscale_config.get('BackendState') == 'Running' - become: yes + become: true + changed_when: false - name: Configure as exit node (if enabled) - command: > + ansible.builtin.command: > tailscale up --advertise-exit-node {% if tailscale_exit_node_allow_lan_access %} --exit-node-allow-lan-access {% endif %} - when: + when: - tailscale_exit_node - current_tailscale_config.get('BackendState') == 'Running' - become: yes + become: true + changed_when: false - name: Set Tailscale preferences - command: > + ansible.builtin.command: > tailscale set {% if tailscale_shields_up %} --shields-up @@ -49,11 +51,22 @@ --ssh=false {% endif %} when: current_tailscale_config.get('BackendState') == 'Running' - become: yes + become: true register: tailscale_prefs_result changed_when: false # These commands don't indicate if changes were made +- name: Configure DNS servers + ansible.builtin.command: > + tailscale set + --dns={{ tailscale_dns_servers | join(',') }} + when: + - tailscale_dns_servers | length > 0 + - current_tailscale_config.get('BackendState') == 'Running' + become: true + register: tailscale_dns_result + changed_when: false + - name: Get final Tailscale status - command: tailscale status + ansible.builtin.command: tailscale status register: tailscale_final_status - changed_when: false \ No newline at end of file + changed_when: false