Note: This guide describes the Python codebase (
src/azlin/). As of v2.3.0-rust, the primary implementation is in Rust (rust/crates/). The Python code is still used for theazlin-pycommand and as the migration bridge. For Rust development, see therust/directory and runcd rust && cargo build --workspaceto build,RUST_MIN_STACK=8388608 cargo test --workspaceto test.
Target Audience: AI agents working on azlin development Purpose: Comprehensive guide to understanding and contributing to azlin Last Updated: 2026-03-08
- This document - Overview and architecture
- ARCHITECTURE.md - Complete system design
- testing/test_strategy.md - Testing approach
- QUICK_REFERENCE.md - Command reference
# 1. Setup environment
uv sync
source .venv/bin/activate
# 2. Run tests (TDD approach)
pytest tests/unit/ -v # Fast feedback
pytest tests/ -m "not e2e" # Skip expensive E2E tests
# 3. Make changes following brick philosophy
# 4. Verify
pytest tests/unit/ -v
ruff check src/- Standard library preference - Minimize external dependencies
- Fail fast - Validate prerequisites before operations
- Zero credentials in code - Delegate to external CLIs (az, gh)
- Explicit over implicit - Clear contracts, no magic
Each module is a self-contained "brick":
- Single responsibility - One clear purpose
- Explicit public API - Define
__all__ - Comprehensive tests - Unit, integration, E2E
- No tight coupling - Modules can be regenerated independently
- Standard patterns - Consistent error handling, logging, validation
| Brick | Module | Purpose | Dependencies |
|---|---|---|---|
| 1 | prerequisites.py |
Verify required tools | stdlib only |
| 2 | azure_auth.py |
Handle Azure authentication | az CLI |
| 3 | ssh_keys.py |
Generate SSH keys | ssh-keygen |
| 4 | vm_provisioning.py |
Create Azure VMs | az CLI |
| 5 | ssh_connector.py |
SSH connection management | ssh, tmux |
| 6 | github_setup.py |
Clone repos on VM | gh, git |
| 7 | npm_config.py |
Configure npm user-local | None |
| 8 | progress.py |
Show real-time progress | stdlib only |
| 9 | notifications.py |
Send completion alerts | imessR (optional) |
Entry Point: cli.py orchestrates all bricks
azlin/
├── src/azlin/
│ ├── cli.py # Main entry point
│ ├── azure_auth.py # Azure authentication
│ ├── vm_provisioning.py # VM provisioning logic
│ ├── remote_exec.py # Remote command execution
│ ├── vm_manager.py # VM lifecycle management
│ ├── vm_lifecycle.py # VM lifecycle operations
│ ├── config_manager.py # Configuration management
│ └── modules/ # Self-contained bricks
│ ├── prerequisites.py
│ ├── ssh_keys.py
│ ├── ssh_connector.py
│ ├── github_setup.py
│ ├── npm_config.py
│ ├── progress.py
│ └── notifications.py
│
├── tests/
│ ├── unit/ # 60% - Fast, isolated tests
│ ├── integration/ # 30% - Multi-module tests
│ └── e2e/ # 10% - Full workflow tests
│
├── docs/
│ ├── ARCHITECTURE.md # Complete system design
│ ├── testing/test_strategy.md # Testing approach
│ ├── QUICK_REFERENCE.md # Command reference
│ └── AI_AGENT_GUIDE.md # This file
│
└── .claude/ # Claude-specific tools
├── agents/ # Agent definitions
├── context/ # Development patterns
└── tools/ # Development tools
- No credentials in code - EVER
- Delegate authentication - Use az CLI, gh CLI
- Validate all inputs - Prevent injection attacks
- Sanitize all outputs - No credential leaks in logs
- Proper file permissions - SSH keys: 600, public: 644
- Azure: Delegated to
az login - GitHub: Delegated to
gh auth login - SSH Keys: Generated locally, never transmitted
- No storage: Zero credentials stored in application
# Example from file_transfer module
1. Reject absolute paths
2. Reject parent directory (..)
3. Reject special files (/dev, /proc)
4. Reject hidden paths (.ssh, .aws)
5. Reject credential paths
6. Validate file extensions
7. Normalize and verify final path# All subprocess calls are validated
- No arbitrary command execution
- Whitelist of allowed commands
- Parameter validation before execution
- Output sanitization before loggingComprehensive protection against credential commits:
.env,.env.*(environment variables)*.pem,*.key(private keys).ssh/,.azure/,.aws/(credential directories)secrets.json,*.credentials(credential files)- 609 lines total covering all secret patterns
/\
/E2E\ 10% - Real VMs, full workflow
/------\
/ INT \ 30% - Multi-module, mocked Azure
/----------\
/ UNIT \ 60% - Single module, fast
-------------
# Fast feedback (< 3 seconds)
pytest tests/unit/ -v
# Skip expensive E2E tests
pytest tests/ -m "not e2e"
# Full suite (creates real VMs, 5-10 min)
pytest tests/
# Single test file
pytest tests/unit/test_vm_provisioning.py -v
# Coverage report
pytest tests/unit/ --cov=src/azlin --cov-report=term-missing- RED: Write failing test first
- GREEN: Implement minimum code to pass
- REFACTOR: Clean up while keeping tests green
Example:
# tests/unit/test_new_feature.py
def test_feature_does_something():
"""Test that feature does X correctly."""
# RED: This will fail
result = new_feature.do_something()
assert result == expected_value
# src/azlin/new_feature.py
def do_something():
# GREEN: Implement to make test pass
return expected_value
# REFACTOR: Clean up implementation
def do_something():
# Better implementation, tests still pass
return compute_expected_value()"""Module docstring - clear purpose statement.
This module handles X by doing Y.
"""
from typing import List, Optional
from dataclasses import dataclass
__all__ = ["PublicClass", "public_function"] # Explicit API
@dataclass
class PublicClass:
"""Public class - appears in __all__."""
field: str
class _PrivateClass:
"""Private class - NOT in __all__."""
pass
def public_function() -> str:
"""Public function - appears in __all__."""
return "result"
def _private_function() -> str:
"""Private function - NOT in __all__."""
return "internal"# Custom exceptions inherit from base
class AzlinError(Exception):
"""Base exception for azlin."""
class ProvisioningError(AzlinError):
"""Raised when VM provisioning fails."""
# Fail fast with clear messages
def provision_vm(config: VMConfig) -> VMDetails:
if not config.name:
raise ProvisioningError("VM name is required")
# ... rest of implementation# Use dataclasses for configuration
from dataclasses import dataclass
from pathlib import Path
@dataclass
class SSHConfig:
"""SSH connection configuration."""
host: str
user: str
key_path: Path
port: int = 22# Use RemoteExecutor for commands on VMs
from azlin.remote_exec import RemoteExecutor
executor = RemoteExecutor(ssh_config)
result = executor.run_command("ls -la /home/azureuser")
if result.exit_code == 0:
print(result.stdout)- Create module file:
src/azlin/modules/new_module.py - Write tests first:
tests/unit/test_new_module.py - Implement module following brick pattern
- Update
__init__.py: Add to__all__ - Run tests:
pytest tests/unit/test_new_module.py -v - Document: Add to this guide if needed
- Update
cli.py: Add@main.command() - Write tests:
tests/unit/test_cli.py - Implement command using existing bricks
- Update help text: Ensure
--helpis clear - Update QUICK_REFERENCE.md: Document command
- Write failing test reproducing the bug (RED)
- Fix the code to make test pass (GREEN)
- Refactor if needed (REFACTOR)
- Verify no other tests broke
- Commit with clear message referencing issue
- Create GitHub issue describing feature
- Create feature branch:
feature/feature-name - Write failing tests (TDD: RED)
- Implement feature (TDD: GREEN)
- Refactor (TDD: REFACTOR)
- Update documentation (README, docs/)
- Create PR with clear description
- Address review feedback
- Merge when approved
1. Prerequisites Check → 2. Azure Auth → 3. SSH Key Gen
↓
4. Cloud-Init Script ← 5. VM Creation ← 6. Resource Group
↓
7. Wait for VM Ready → 8. Get Public IP → 9. SSH Connect
- Location:
vm_provisioning.py._generate_cloud_init() - Purpose: Automate VM setup on first boot
- Installs: Docker, Azure CLI, GitHub CLI, Git, Node.js, Python, Rust, Go, .NET, AI CLI tools
- Configures: npm user-local, SSH, tmux
azlin- Provision new VM or connect to existingazlin list- List all VMsazlin status- Show detailed VM statusazlin start <name>- Start stopped VMazlin stop <name>- Deallocate VM (save costs)azlin kill <name>- Delete VM and resourcesazlin killall- Delete all VMs in resource group
- ✅
azlincreates VM and connects via SSH with tmux - ✅
azlin --repo <url>clones repo on VM - ✅ All development tools installed on VM
- ✅ SSH key-based authentication works
- ✅ Tmux session persists across reconnects
- ✅ npm configured for user-local installs
- ✅ AI CLI tools (Copilot, Codex, Claude) pre-installed
- ✅ Total provisioning time < 7 minutes
- ✅ Test coverage > 80%
- ✅ Zero credentials in logs or code
- ✅ Works on macOS, Linux, WSL, Windows
- ✅ Proper error messages for all failures
- ✅ All modules follow brick philosophy
- ✅ Clear public API contracts (
__all__) - ✅ Comprehensive test suite (TDD pyramid)
- ✅ Standard library preference
- ✅ Security best practices followed
# Ensure src/ is in PYTHONPATH
export PYTHONPATH="${PYTHONPATH}:${PWD}/src"
# Or use editable install
uv pip install -e .# Run specific test with verbose output
pytest tests/unit/test_module.py::test_function -vv
# Show stdout/stderr
pytest tests/unit/test_module.py -s
# Stop on first failure
pytest tests/unit/ -x# Check Azure login status
az account show
# Re-authenticate
az login
# Set subscription
az account set --subscription "subscription-id"- ARCHITECTURE.md - Complete system design
- testing/test_strategy.md - Testing guidelines
- QUICK_REFERENCE.md - Command reference
- UV_USAGE.md - uv package manager guide
- Azure CLI: https://docs.microsoft.com/cli/azure/
- GitHub CLI: https://cli.github.com/manual/
- Python Testing: https://docs.pytest.org/
- uv Documentation: https://docs.astral.sh/uv/
- pytest: Testing framework
- ruff: Fast Python linter
- pyright: Type checker
- uv: Package manager
- pre-commit: Git hooks
- Always use TDD: Write tests first (RED → GREEN → REFACTOR)
- Follow brick philosophy: Self-contained, single responsibility
- Explicit public APIs: Define
__all__in every module - Comprehensive docstrings: Explain purpose, parameters, returns
- Security first: Never store credentials, validate all inputs
- Update documentation: Keep this guide and others current
feat: Add new feature
fix: Fix bug in module
docs: Update documentation
test: Add tests for feature
refactor: Improve code structure
chore: Maintenance tasks
- Create feature branch from main
- Implement with TDD (tests first)
- Ensure all tests pass
- Update documentation
- Create PR with clear description
- Address review feedback
- Merge when approved
- Brick: Self-contained module with single responsibility
- Cloud-Init: First-boot VM configuration system
- Delegation Pattern: Authentication handled by external tools (az, gh)
- E2E: End-to-end tests (expensive, use real resources)
- TDD: Test-Driven Development (RED → GREEN → REFACTOR)
- VM: Virtual Machine on Azure
- uvx: Tool for running Python packages without installation
Last Updated: 2025-10-15 Maintainer: azlin project License: MIT