{"id":44317263,"url":"https://github.com/basher83/andromeda-orchestration","last_synced_at":"2026-02-11T05:14:57.944Z","repository":{"id":310553043,"uuid":"1024021396","full_name":"basher83/andromeda-orchestration","owner":"basher83","description":null,"archived":false,"fork":false,"pushed_at":"2026-02-07T21:45:21.000Z","size":3309,"stargazers_count":1,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-07T22:54:29.023Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Jinja","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/basher83.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-22T04:32:21.000Z","updated_at":"2026-02-06T04:41:43.000Z","dependencies_parsed_at":"2025-08-18T21:27:50.147Z","dependency_job_id":"c3db0c0d-d29f-4e14-ac29-cae608162dce","html_url":"https://github.com/basher83/andromeda-orchestration","commit_stats":null,"previous_names":["basher83/andromeda-orchestration"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/basher83/andromeda-orchestration","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/basher83%2Fandromeda-orchestration","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/basher83%2Fandromeda-orchestration/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/basher83%2Fandromeda-orchestration/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/basher83%2Fandromeda-orchestration/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/basher83","download_url":"https://codeload.github.com/basher83/andromeda-orchestration/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/basher83%2Fandromeda-orchestration/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29327152,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-11T03:52:29.695Z","status":"ssl_error","status_checked_at":"2026-02-11T03:52:23.094Z","response_time":97,"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":[],"created_at":"2026-02-11T05:14:57.782Z","updated_at":"2026-02-11T05:14:57.935Z","avatar_url":"https://github.com/basher83.png","language":"Jinja","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Andromeda Orchestration\n\n---\n\n![GitHub last commit](https://img.shields.io/github/last-commit/basher83/andromeda-orchestration?path=README.md\u0026display_timestamp=author\u0026style=plastic\u0026logo=github)\n[![CI](https://github.com/basher83/andromeda-orchestration/actions/workflows/ci.yml/badge.svg)](https://github.com/basher83/andromeda-orchestration/actions/workflows/ci.yml)\n[![MegaLinter](https://github.com/basher83/andromeda-orchestration/workflows/MegaLinter/badge.svg?branch=main)](https://github.com/basher83/andromeda-orchestration/actions?query=workflow%3AMegaLinter+branch%3Amain)\n\n![Ansible](https://img.shields.io/badge/Ansible-000000?style=plastic\u0026logo=ansible\u0026logoColor=)\n\n![Proxmox](https://img.shields.io/badge/Proxmox-000000?style=plastic\u0026logo=proxmox\u0026logoColor=)\n\n![Vault](https://img.shields.io/badge/Vault-000000?style=plastic\u0026logo=vault\u0026logoColor=)\n![Nomad](https://img.shields.io/badge/Nomad-000000?style=plastic\u0026logo=nomad\u0026logoColor=)\n![Consul](https://img.shields.io/badge/Consul-000000?style=plastic\u0026logo=consul\u0026logoColor=)\n\n![Tailscale](https://img.shields.io/badge/Tailscale-000000?style=plastic\u0026logo=tailscale\u0026logoColor=)\n\n![NetBox](https://img.shields.io/badge/NetBox-000000?style=plastic\u0026logo=netbox\u0026logoColor=)\n![Infisical](https://img.shields.io/badge/Infisical-000000?style=plastic\u0026logo=infisical\u0026logoColor=)\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/basher83/assets/refs/heads/main/space-gifs/undraw_space-exploration_dhu1.svg\" alt=\"Space Exploration\" width=\"400\"\u003e\n\u003c/p\u003e\n\nAn Ansible automation project for comprehensive homelab infrastructure management, with NetBox integration for network\nsource-of-truth and secure credential management through Infisical.\n\n## Overview\n\nThis project provides a framework for managing network infrastructure using Ansible with:\n\n- Multiple dynamic inventory sources (Proxmox, NetBox, Tailscale)\n- Secure credential management via Infisical\n- Best practices for Ansible project organization\n\n**Infrastructure Foundation**: The underlying infrastructure (Proxmox clusters, VMs, networking) is provisioned and managed via [terraform-homelab](https://github.com/basher83/terraform-homelab) using Terraform/OpenTofu with Scalr.\n\n## Prerequisites\n\n- **Python** 3.9+ with **uv** package manager\n- **Ansible** 2.15+ with ansible-core\n- **Ansible Galaxy Collections** (see `requirements.yml`):\n  - `infisical.vault` - Secrets management\n  - `community.general` - General purpose modules\n  - `community.hashi_vault` - HashiCorp Vault modules\n  - `ansible.utils` - Utility modules and filters\n- **Python Packages** (required for Ansible collections):\n  - `netaddr` (python3-netaddr) - Required for `ansible.utils.ipaddr` filter\n- **Infisical** account and machine identity\n- **macOS** users: Local Network permissions for Python (see [Troubleshooting](docs/getting-started/troubleshooting.md))\n- Docker (optional, for execution environments)\n\n### Python Dependencies\n\nThe project uses **uv** for dependency management. Available dependency groups:\n\n- **Core dependencies**: Basic runtime requirements\n  - `netaddr` - Required for IP address validation and `ansible.utils.ipaddr` filter\n- **Dev dependencies**: Development tools (`ansible-lint`, `pytest`, `ruff`, `mypy`, etc.)\n- **Secrets dependencies**: Infisical SDK for secrets management\n\n## Quick Start\n\n1. **Clone the repository**\n\n   ```bash\n   git clone \u003crepository-url\u003e\n   cd andromeda-orchestration\n   ```\n\n1. **Install Python dependencies**\n\n   ```bash\n   # Install core Python dependencies\n   uv sync\n\n   # For development (optional - includes ansible-lint, pytest, ruff, etc.)\n   uv sync --extra dev\n\n   # For secrets management (optional - includes infisical SDK)\n   uv sync --extra secrets\n\n   # For both development and secrets (combine extras)\n   uv sync --extra dev --extra secrets\n   ```\n\n1. **Install Ansible Galaxy collections**\n\n   ```bash\n   # Install required Ansible collections (community.general, infisical.vault, etc.)\n   uv run ansible-galaxy collection install -r requirements.yml\n\n   # Note: This command is idempotent and uses local caching.\n   # Re-running will skip already-installed collections and only download missing/updated ones.\n   # Use --force to re-download all collections if needed.\n   ```\n\n1. **Run the setup script**\n\n   ```bash\n   ./scripts/setup.sh\n   # Or use mise for complete setup with dev tools\n   mise run setup\n   ```\n\n   The setup script will:\n   - Verify prerequisites (Ansible, Python)\n   - Install Ansible Galaxy collections (if not already done)\n   - Set up Python virtual environment with uv\n   - Create necessary directory structure\n\n1. **Configure secrets and authentication**\n\n## SECURITY: Never commit .mise.local.toml; it is gitignored and must stay local\n\n```bash\n# Copy the template and add your secrets\ncp .mise.local.toml.example .mise.local.toml\n\n# Edit with your actual tokens and credentials\n# The file is gitignored and won't be committed\n$EDITOR .mise.local.toml\n\n# Mise will automatically load these environment variables\n```\n\n1. **Test the setup**\n\n   ```bash\n   uv run ansible-inventory -i inventory/og-homelab/infisical.proxmox.yml --list\n   ```\n\n## Development\n\n### Code Quality Tools\n\nThis project uses comprehensive linting and testing:\n\n- **ansible-lint** - Ansible best practices and style guide\n- **yamllint** - YAML file formatting\n- **ruff** - Python linting and formatting\n- **mypy** - Python type checking\n- **pre-commit** - Git hooks for automated checks (see [docs/pre-commit-setup.md](docs/pre-commit-setup.md))\n\n### Security Tools\n\nIntegrated security scanning:\n\n- **Infisical** - Secrets detection and management\n- **KICS** - Infrastructure-as-Code security scanning\n- **Pre-commit hooks** - Automated security checks on commit\n\n### Quick Commands\n\n```bash\n# Show all available tasks\nmise tasks\n\n# Run all linters\nmise run lint\n\n# Ultra-fast MegaLinter testing (no Node.js required)\nmise run act-fast\n# Or: ./scripts/mega-linter-runner.sh\n\n# Streamlined local testing with GHCR registry (recommended)\nmise run megalinter-local\n# Or: ./scripts/run-megalinter-local.sh\n\n# Run tests\nmise run test\n\n# Run security scans (Infisical + KICS)\nmise run security\n\n# Run individual security scans\nmise run security:secrets  # Infisical secrets detection\nmise run security:kics     # Infrastructure security scan\n\n# Check cluster health\nmise run status\n\n# Setup development environment\nmise run setup\n```\n\nSee [docs/implementation/dns-ipam/testing-strategy.md](docs/implementation/dns-ipam/testing-strategy.md) for detailed testing information.\n\n**MegaLinter Status**: The badge above shows the status of our automated code quality checks. Green means all linters pass! For fast local testing without Node.js dependencies, use `mise run act-fast`.\n\n**Configuration Organization**: Linter configuration files (`.ansible-lint`, `.yamllint`, `.markdownlint.json`) in the repository root are symbolic links pointing to organized configurations in `.github/linters/` for better maintainability while maintaining backward compatibility.\n\n**Note on uv and Ansible**: This project uses `uv pip install` in a virtual environment rather than `uv tool install` to ensure all Ansible executables are available. See [docs/getting-started/uv-ansible-notes.md](docs/getting-started/uv-ansible-notes.md) for details.\n\n## Directory Structure\n\n```text\n├── docs/                   # Documentation\n│   ├── infisical-setup-and-migration.md\n│   ├── dns-ipam-implementation-plan.md\n│   └── troubleshooting.md\n├── inventory/              # Dynamic inventory configurations\n│   ├── og-homelab/        # Original homelab cluster inventories\n│   └── doggos-homelab/    # Doggos cluster inventories\n├── playbooks/              # Ansible playbooks\n│   ├── assessment/        # Infrastructure assessment playbooks\n│   ├── examples/          # Example playbooks\n│   └── infrastructure/    # Infrastructure management\n├── plugins/               # Custom Ansible plugins\n│   └── lookup/           # Custom lookup plugins\n├── roles/                 # Ansible roles (future)\n├── scripts/              # Support scripts\n└── tests/                # Test playbooks\n\n```\n\n## Usage\n\n### Running Commands with Infisical\n\nUse `uv run` to execute Ansible commands with Infisical secret management:\n\n```bash\n# List inventory\nuv run ansible-inventory -i inventory/og-homelab/infisical.proxmox.yml --list\n\n# Run a playbook\nuv run ansible-playbook playbooks/site.yml -i inventory/og-homelab/infisical.proxmox.yml\n\n# Ad-hoc command\nuv run ansible all -i inventory/og-homelab/infisical.proxmox.yml -m ping\n```\n\n### Managing Secrets\n\nSee [docs/implementation/secrets-management/infisical-setup.md](docs/implementation/secrets-management/infisical-setup.md) for detailed instructions on:\n\n- Setting up Infisical machine identity\n- Organizing secrets in projects and environments\n- Using secrets in playbooks and inventories\n\n## Configuration\n\n### Ansible Configuration (`ansible.cfg`)\n\n- Configured for local plugin directories\n- Inventory path set to `./inventory`\n- Host key checking disabled for development\n\n### Service Endpoints (`inventory/environments/all/service-endpoints.yml`)\n\nCentralized service endpoint configuration to avoid hardcoded IPs:\n\n- **Consul**: `{{ service_endpoints.consul.addr }}`\n- **Nomad**: `{{ service_endpoints.nomad.addr }}`\n- **Vault**: `{{ service_endpoints.vault.addr }}`\n\n#### Mandatory IP Validation\n\nAll playbooks must include the pre_tasks validator to enforce no hardcoded IPv4/IPv6 literals:\n\npre_tasks:\n\n- name: Enforce dynamic-inventory pattern (no hardcoded IPs)\n    ansible.builtin.import_tasks: \"{{ playbook_dir }}/../../../tasks/validate-no-hardcoded-ips.yml\"\n    vars:\n      validate_allowlist:\n        - '127.0.0.1'\n        - '::1'\n    tags: ['validate']\n\nOverride via environment variables:\n\n```bash\n# Export examples (add to ~/.bashrc or run before ansible commands)\nexport CONSUL_HTTP_ADDR=\"http://consul.service.consul:8500\"\nexport NOMAD_ADDR=\"http://nomad.service.consul:4646\"\nexport VAULT_ADDR=\"https://vault.service.consul:8200\"\n\n# One-off command example (sets VAULT_ADDR for single command)\nVAULT_ADDR=\"https://vault.service.consul:8200\" uv run ansible-playbook playbook.yml\n```\n\nDefaults to service discovery addresses with direct IP fallbacks.\n\nNote: To comply with the no-hardcoded-IP policy, avoid committing private IP\ndefaults in shared inventory. If direct access is required, provide values via\nenvironment variables or in environment-specific inventory only, and update the\nIP-validation allowlist accordingly.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbasher83%2Fandromeda-orchestration","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbasher83%2Fandromeda-orchestration","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbasher83%2Fandromeda-orchestration/lists"}