ADR-0006: Modular Dependency Management Strategy
Status
Accepted
Context
Qubinode Navigator needed to integrate with various external services and cloud providers including GitHub, GitLab, OneDev, Cockpit, Route53, and multiple cloud platforms (Equinix, Hetzner). Each integration has unique configuration requirements, dependencies, and setup procedures. The project required a strategy to manage these integrations without creating a monolithic, tightly-coupled system that would be difficult to maintain, test, and extend with new services.
Decision
Implement a modular dependency management strategy using separate directories under dependancies/ for each external service integration. Each module contains its own configuration files, setup scripts, and documentation, allowing independent development, testing, and deployment of integrations while maintaining loose coupling with the core system.
Consequences
Positive Consequences
- Enables independent development and testing of service integrations
- Reduces coupling between core system and external service dependencies
- Facilitates selective deployment of only required integrations
- Simplifies maintenance and updates of individual service integrations
- Allows parallel development by different team members
- Makes it easier to add new service integrations
- Improves system modularity and architectural clarity
- Enables easier troubleshooting of integration-specific issues
Negative Consequences
- Increases overall project complexity with multiple modules
- Potential for code duplication across similar integrations
- Requires discipline to maintain consistent patterns across modules
- May complicate dependency resolution between modules
- Additional overhead in managing multiple configuration sets
- Potential for integration drift if not properly coordinated
Alternatives Considered
- Monolithic integration approach - Rejected due to tight coupling and maintenance complexity
- Single configuration file for all integrations - Would create unwieldy configuration management
- External package management - Too complex for the current project scope
- Plugin-based architecture - Over-engineered for current requirements
- Git submodules for integrations - Would complicate repository management
Evidence Supporting This Decision
- Separate directories for each integration:
cockpit-ssl/,github/,gitlab/,onedev/,route53/ - Cloud provider-specific modules:
equinix-rocky/,hetzner/ - Independent configuration and setup within each module
- Modular approach allows selective integration deployment
- Clear separation of concerns between different service types
Implementation Details
Directory Structure
dependancies/
├── cockpit-ssl/ # Web management interface SSL setup
├── equinix-rocky/ # Equinix Metal with Rocky Linux
├── github/ # GitHub integration and automation
├── gitlab/ # GitLab integration and CI/CD
├── hetzner/ # Hetzner cloud provider integration
├── onedev/ # OneDev Git server setup
└── route53/ # AWS Route53 DNS management
Module Characteristics
Each dependency module typically contains:
- Configuration Files: Service-specific settings and parameters
- Setup Scripts: Installation and configuration automation
- Documentation: Service-specific setup and usage instructions
- Templates: Configuration templates for different environments
- Validation Scripts: Health checks and integration testing
Integration Patterns
- Loose Coupling: Modules interact with core system through well-defined interfaces
- Configuration Injection: Core system provides environment context to modules
- Service Discovery: Modules register their capabilities with the core system
- Event-Driven: Modules respond to system events and lifecycle hooks
Example Module Structure
dependancies/github/
├── config/ # GitHub-specific configuration
├── scripts/ # Setup and management scripts
├── templates/ # Configuration templates
├── README.md # Module documentation
└── validate.sh # Integration validation
Core System Integration
- Modules are discovered and loaded dynamically during setup
- Core configuration system provides environment context to modules
- Shared utilities and libraries available to all modules
- Consistent logging and error handling across modules
Dependency Resolution
- Explicit Dependencies: Modules declare their dependencies clearly
- Lazy Loading: Modules loaded only when required
- Graceful Degradation: System continues to function if optional modules fail
- Validation: Pre-deployment checks ensure required dependencies are available
Configuration Management
- Environment-Specific: Modules adapt to different deployment environments
- Template-Based: Configuration templates with variable substitution
- Validation: Configuration validation before deployment
- Secrets Management: Integration with vault system for sensitive data
Benefits Realized
Development Benefits
- Parallel Development: Teams can work on different integrations simultaneously
- Focused Testing: Each module can be tested independently
- Clear Ownership: Specific teams can own specific integrations
- Reduced Complexity: Developers only need to understand relevant modules
Operational Benefits
- Selective Deployment: Deploy only required integrations
- Easier Troubleshooting: Issues isolated to specific modules
- Incremental Updates: Update individual integrations without affecting others
- Resource Optimization: Load only necessary components
Maintenance Benefits
- Isolated Changes: Changes to one integration don’t affect others
- Version Management: Each module can have independent versioning
- Documentation: Service-specific documentation co-located with code
- Testing: Focused testing strategies for each integration type
Quality Assurance
Consistency Patterns
- Naming Conventions: Consistent naming across all modules
- Configuration Patterns: Standard configuration file structures
- Error Handling: Consistent error reporting and logging
- Documentation Standards: Uniform documentation requirements
Validation Requirements
- Integration Testing: Each module must pass integration tests
- Configuration Validation: All configurations validated before deployment
- Dependency Checking: Dependencies verified during setup
- Health Monitoring: Runtime health checks for active integrations
Related Decisions
- ADR-0001: Container-First Execution Model with Ansible Navigator
- ADR-0002: Multi-Cloud Inventory Strategy with Environment-Specific Configurations
- ADR-0003: Dynamic Configuration Management with Python
- ADR-0004: Security Architecture with Ansible Vault and AnsibleSafe
- ADR-0005: KVM/Libvirt Virtualization Platform Choice
Date
2025-01-09
Stakeholders
- DevOps Team
- Infrastructure Team
- Integration Teams
- Cloud Operations Team
- Project Maintainers