infra/CLAUDE.md
2025-10-05 13:12:28 -05:00

5.2 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Repository Overview

This is a multi-environment infrastructure-as-code repository managing:

  • Ansible: Configuration management for servers across multiple environments (VNTX, home, app servers)
  • Terraform: DNS infrastructure management across DNSimple, Porkbun, and PowerDNS
  • Home Lab: Server configurations with Tailscale integration

Common Commands

Ansible Operations

# Run main playbook
cd ansible && ./run.sh

# Bootstrap new host
make bootstrap-init HOSTNAME=hostname ANSIBLE_HOST=ip_address

# Run specific playbook
ansible-playbook general.yml

# Run with specific tags
ansible-playbook -t caddy general.yml

# Gather facts from all hosts
make facts

Terraform Operations

IMPORTANT: Use OpenTofu (tofu) instead of terraform for all operations.

cd terraform
tofu init
tofu plan
tofu apply

# Format terraform files before committing
tofu fmt

Kubernetes Operations (K3s cluster at 204.110.191.2)

# Set kubeconfig
export KUBECONFIG=/Users/graham/dev/infra/home/ansible/kubeconfig

# Deploy APRS.me application
cd home/cluster/aprs
./deploy.sh

# Check deployment status
kubectl get pods -n aprs
kubectl get svc -n aprs

Architecture

Directory Structure

  • ansible/ - Ansible playbooks and roles for server configuration

    • roles/ - Reusable roles (base, caddy, docker, resolvers, etc.)
    • group_vars/ - Group-specific variables
    • host_vars/ - Host-specific variables
    • Main playbooks: playbook.yml, general.yml, bootstrap.yml
  • home/terraform/ - DNS infrastructure management

    • Manages domains: w5isp.com, vntx.net/org, manero.org, mcintire.me, gridmap.org
    • Providers: DNSimple, Porkbun, PowerDNS (reverse DNS)
  • home/ - Home lab configurations

    • cluster/ - Kubernetes application deployments
      • aprs/ - APRS.me deployment with PostgreSQL/PostGIS and Redis
      • wavelog/ - Wavelog amateur radio logging application
    • terraform/ - DNS infrastructure management

Key Infrastructure Services

Monitoring: Icinga2 with MariaDB backend DNS: Unbound resolvers, PowerDNS for reverse zones VPN: Tailscale integration across environments Web Proxy: Caddy for reverse proxy and SSL termination

Security Notes

  • Ansible user (UID 10001) with passwordless sudo
  • SSH keys fetched from GitHub for authentication
  • Tailscale requires TAILSCALE_KEY environment variable
  • Terraform credentials should use environment variables (TF_VAR_*)

Development Workflow

Adding New Hosts

  1. Add host to ansible/hosts inventory
  2. Create host_vars file if needed
  3. Run bootstrap: make bootstrap-init HOSTNAME=x ANSIBLE_HOST=y
  4. Apply configuration: ansible-playbook -l hostname general.yml

DNS Changes

  1. Edit appropriate home/terraform/dns_*.tf file
  2. Run tofu fmt to format
  3. Review with tofu plan
  4. Apply with tofu apply

Testing

Ansible

# Syntax check
ansible-playbook --syntax-check playbook.yml

# Dry run
ansible-playbook --check playbook.yml

# Test on specific host
ansible-playbook -l hostname playbook.yml

Terraform

tofu validate
tofu plan

Recent Infrastructure Updates

K3s Cluster at 204.110.191.2

  • Purpose: Home lab Kubernetes cluster
  • Node1 IPs:
    • Public: 204.110.191.2
    • Tailscale: 100.102.235.20
    • Internal: 10.0.101.21
  • API Access: Currently only available on 10.0.101.21:6443 (not on Tailscale)
  • Context: Use kubectl config use-context homelab to access
  • Storage: Longhorn for persistent volumes
  • Applications:
    • APRS.me: Amateur radio APRS tracking application (https://aprs.me)
      • PostgreSQL 17 with PostGIS (100GB Longhorn PVC)
      • Redis for caching
      • 2-replica StatefulSet for high availability
      • Erlang clustering enabled
      • LoadBalancer service assigned: 10.0.101.32
      • Note: ghcr.io/aprsme/aprs.me:latest requires authentication
      • Deploy with: cd home/cluster/aprs && ./deploy.sh
    • Wavelog: Amateur radio logging application (https://log.w5isp.com)
      • MariaDB 11 database (10GB storage)
      • 20GB storage for configs, backups, uploads, QSL cards
      • PHP application with custom limits (50MB uploads, 256MB memory)
      • Deploy with: cd home/cluster/wavelog && ./deploy.sh

New Server: w5isp.w5isp.com (204.110.191.200)

  • Purpose: Single-node server running Debian 13
  • Features:
    • Web services with automatic SSL
    • Single public IP handles all services

DNS Configuration

  • Photos: photos.w5isp.com → 204.110.191.212 (Caddy) → 100.107.11.77:2283
  • Mailcow: mcintire.me mail records → mail.w5isp.com (sync.w5isp.com at 204.110.191.216)
    • Full mail setup with MX, SPF, DKIM, DMARC records
    • Autodiscover/Autoconfig for mail clients
    • Backup MX: mail.nsnw.ca (priority 20)
    • Note: sync.w5isp.com is the Mailcow server (not using Caddy proxy)

Code Guidelines

Communication Practices

  • Do not ever reply with "you're right". Just fix the issue
  • Never say you're right, just accept it and move on

Notes for Claude

  • As you learn new things, keep claude.md updated

Clusters

  • k3s cluster at 204.110.191.2