# Configuration Guide

This comprehensive guide explains the configuration system of the Infrastructure Automation platform, helping you understand, customize, and manage all configuration aspects.

## What You'll Learn

- Understanding the configuration hierarchy and precedence
- Working with different configuration file types
- Configuration interpolation and templating
- Environment-specific configurations
- User customization and overrides
- Validation and troubleshooting
- Advanced configuration patterns

## Configuration Architecture

### Configuration Hierarchy

The system uses a layered configuration approach with clear precedence rules:

```plaintext
Runtime CLI arguments (highest precedence)
    ↓ (overrides)
Environment Variables
    ↓ (overrides)
Infrastructure Config (./.provisioning.toml)
    ↓ (overrides)
Project Config (./provisioning.toml)
    ↓ (overrides)
User Config (~/.config/provisioning/config.toml)
    ↓ (overrides)
System Defaults (config.defaults.toml) (lowest precedence)
```plaintext

### Configuration File Types

| File Type | Purpose | Location | Format |
|-----------|---------|----------|--------|
| **System Defaults** | Base system configuration | `config.defaults.toml` | TOML |
| **User Config** | Personal preferences | `~/.config/provisioning/config.toml` | TOML |
| **Project Config** | Project-wide settings | `./provisioning.toml` | TOML |
| **Infrastructure Config** | Infra-specific settings | `./.provisioning.toml` | TOML |
| **Environment Config** | Environment overrides | `config.{env}.toml` | TOML |
| **Infrastructure Definitions** | Infrastructure as Code | `main.ncl`, `*.ncl` | Nickel |

## Understanding Configuration Sections

### Core System Configuration

```toml
[core]
version = "1.0.0"           # System version
name = "provisioning"       # System identifier
```plaintext

### Path Configuration

The most critical configuration section that defines where everything is located:

```toml
[paths]
# Base directory - all other paths derive from this
base = "/usr/local/provisioning"

# Derived paths (usually don't need to change these)
kloud = "{{paths.base}}/infra"
providers = "{{paths.base}}/providers"
taskservs = "{{paths.base}}/taskservs"
clusters = "{{paths.base}}/cluster"
resources = "{{paths.base}}/resources"
templates = "{{paths.base}}/templates"
tools = "{{paths.base}}/tools"
core = "{{paths.base}}/core"

[paths.files]
# Important file locations
settings_file = "settings.ncl"
keys = "{{paths.base}}/keys.yaml"
requirements = "{{paths.base}}/requirements.yaml"
```plaintext

### Debug and Logging

```toml
[debug]
enabled = false             # Enable debug mode
metadata = false           # Show internal metadata
check = false              # Default to check mode (dry run)
remote = false            # Enable remote debugging
log_level = "info"        # Logging verbosity
no_terminal = false       # Disable terminal features
```plaintext

### Output Configuration

```toml
[output]
file_viewer = "less"       # File viewer command
format = "yaml"           # Default output format (json, yaml, toml, text)
```plaintext

### Provider Configuration

```toml
[providers]
default = "local"         # Default provider

[providers.aws]
api_url = ""              # AWS API endpoint (blank = default)
auth = ""                 # Authentication method
interface = "CLI"         # Interface type (CLI or API)

[providers.upcloud]
api_url = "https://api.upcloud.com/1.3"
auth = ""
interface = "CLI"

[providers.local]
api_url = ""
auth = ""
interface = "CLI"
```plaintext

### Encryption (SOPS) Configuration

```toml
[sops]
use_sops = true           # Enable SOPS encryption
config_path = "{{paths.base}}/.sops.yaml"

# Search paths for Age encryption keys
key_search_paths = [
    "{{paths.base}}/keys/age.txt",
    "~/.config/sops/age/keys.txt"
]
```plaintext

## Configuration Interpolation

The system supports powerful interpolation patterns for dynamic configuration values.

### Basic Interpolation Patterns

#### Path Interpolation

```toml
# Reference other path values
templates = "{{paths.base}}/my-templates"
custom_path = "{{paths.providers}}/custom"
```plaintext

#### Environment Variable Interpolation

```toml
# Access environment variables
user_home = "{{env.HOME}}"
current_user = "{{env.USER}}"
custom_path = "{{env.CUSTOM_PATH || /default/path}}"  # With fallback
```plaintext

#### Date/Time Interpolation

```toml
# Dynamic date/time values
log_file = "{{paths.base}}/logs/app-{{now.date}}.log"
backup_dir = "{{paths.base}}/backups/{{now.timestamp}}"
```plaintext

#### Git Information Interpolation

```toml
# Git repository information
deployment_branch = "{{git.branch}}"
version_tag = "{{git.tag}}"
commit_hash = "{{git.commit}}"
```plaintext

#### Cross-Section References

```toml
# Reference values from other sections
database_host = "{{providers.aws.database_endpoint}}"
api_key = "{{sops.decrypted_key}}"
```plaintext

### Advanced Interpolation

#### Function Calls

```toml
# Built-in functions
config_path = "{{path.join(env.HOME, .config, provisioning)}}"
safe_name = "{{str.lower(str.replace(project.name, ' ', '-'))}}"
```plaintext

#### Conditional Expressions

```toml
# Conditional logic
debug_level = "{{debug.enabled && 'debug' || 'info'}}"
storage_path = "{{env.STORAGE_PATH || path.join(paths.base, 'storage')}}"
```plaintext

### Interpolation Examples

```toml
[paths]
base = "/opt/provisioning"
workspace = "{{env.HOME}}/provisioning-workspace"
current_project = "{{paths.workspace}}/{{env.PROJECT_NAME || 'default'}}"

[deployment]
environment = "{{env.DEPLOY_ENV || 'development'}}"
timestamp = "{{now.iso8601}}"
version = "{{git.tag || git.commit}}"

[database]
connection_string = "postgresql://{{env.DB_USER}}:{{env.DB_PASS}}@{{env.DB_HOST || 'localhost'}}/{{env.DB_NAME}}"

[notifications]
slack_channel = "#{{env.TEAM_NAME || 'general'}}-notifications"
email_subject = "Deployment {{deployment.environment}} - {{deployment.timestamp}}"
```plaintext

## Environment-Specific Configuration

### Environment Detection

The system automatically detects the environment using:

1. **PROVISIONING_ENV** environment variable
2. **Git branch patterns** (dev, staging, main/master)
3. **Directory patterns** (development, staging, production)
4. **Explicit configuration**

### Environment Configuration Files

Create environment-specific configurations:

#### Development Environment (`config.dev.toml`)

```toml
[core]
name = "provisioning-dev"

[debug]
enabled = true
log_level = "debug"
metadata = true

[providers]
default = "local"

[cache]
enabled = false  # Disable caching for development

[notifications]
enabled = false  # No notifications in dev
```plaintext

#### Testing Environment (`config.test.toml`)

```toml
[core]
name = "provisioning-test"

[debug]
enabled = true
check = true     # Default to check mode in testing
log_level = "info"

[providers]
default = "local"

[infrastructure]
auto_cleanup = true  # Clean up test resources
resource_prefix = "test-{{git.branch}}-"
```plaintext

#### Production Environment (`config.prod.toml`)

```toml
[core]
name = "provisioning-prod"

[debug]
enabled = false
log_level = "warn"

[providers]
default = "aws"

[security]
require_approval = true
audit_logging = true
encrypt_backups = true

[notifications]
enabled = true
critical_only = true
```plaintext

### Environment Switching

```bash
# Set environment for session
export PROVISIONING_ENV=dev
provisioning env

# Use environment for single command
provisioning --environment prod server create

# Switch environment permanently
provisioning env set prod
```plaintext

## User Configuration Customization

### Creating Your User Configuration

```bash
# Initialize user configuration from template
provisioning init config

# Or copy and customize
cp config-examples/config.user.toml ~/.config/provisioning/config.toml
```plaintext

### Common User Customizations

#### Developer Setup

```toml
[paths]
base = "/Users/alice/dev/provisioning"

[debug]
enabled = true
log_level = "debug"

[providers]
default = "local"

[output]
format = "json"
file_viewer = "code"

[sops]
key_search_paths = [
    "/Users/alice/.config/sops/age/keys.txt"
]
```plaintext

#### Operations Engineer Setup

```toml
[paths]
base = "/opt/provisioning"

[debug]
enabled = false
log_level = "info"

[providers]
default = "aws"

[output]
format = "yaml"

[notifications]
enabled = true
email = "ops-team@company.com"
```plaintext

#### Team Lead Setup

```toml
[paths]
base = "/home/teamlead/provisioning"

[debug]
enabled = true
metadata = true
log_level = "info"

[providers]
default = "upcloud"

[security]
require_confirmation = true
audit_logging = true

[sops]
key_search_paths = [
    "/secure/keys/team-lead.txt",
    "~/.config/sops/age/keys.txt"
]
```plaintext

## Project-Specific Configuration

### Project Configuration File (`provisioning.toml`)

```toml
[project]
name = "web-application"
description = "Main web application infrastructure"
version = "2.1.0"
team = "platform-team"

[paths]
# Project-specific path overrides
infra = "./infrastructure"
templates = "./custom-templates"

[defaults]
# Project defaults
provider = "aws"
region = "us-west-2"
environment = "development"

[cost_controls]
max_monthly_budget = 5000.00
alert_threshold = 0.8

[compliance]
required_tags = ["team", "environment", "cost-center"]
encryption_required = true
backup_required = true

[notifications]
slack_webhook = "https://hooks.slack.com/services/..."
team_email = "platform-team@company.com"
```plaintext

### Infrastructure-Specific Configuration (`.provisioning.toml`)

```toml
[infrastructure]
name = "production-web-app"
environment = "production"
region = "us-west-2"

[overrides]
# Infrastructure-specific overrides
debug.enabled = false
debug.log_level = "error"
cache.enabled = true

[scaling]
auto_scaling_enabled = true
min_instances = 3
max_instances = 20

[security]
vpc_id = "vpc-12345678"
subnet_ids = ["subnet-12345678", "subnet-87654321"]
security_group_id = "sg-12345678"

[monitoring]
enabled = true
retention_days = 90
alerting_enabled = true
```plaintext

## Configuration Validation

### Built-in Validation

```bash
# Validate current configuration
provisioning validate config

# Detailed validation with warnings
provisioning validate config --detailed

# Strict validation mode
provisioning validate config strict

# Validate specific environment
provisioning validate config --environment prod
```plaintext

### Custom Validation Rules

Create custom validation in your configuration:

```toml
[validation]
# Custom validation rules
required_sections = ["paths", "providers", "debug"]
required_env_vars = ["AWS_REGION", "PROJECT_NAME"]
forbidden_values = ["password123", "admin"]

[validation.paths]
# Path validation rules
base_must_exist = true
writable_required = ["paths.base", "paths.cache"]

[validation.security]
# Security validation
require_encryption = true
min_key_length = 32
```plaintext

## Troubleshooting Configuration

### Common Configuration Issues

#### Issue 1: Path Not Found Errors

```bash
# Problem: Base path doesn't exist
# Check current configuration
provisioning env | grep paths.base

# Verify path exists
ls -la /path/shown/above

# Fix: Update user config
nano ~/.config/provisioning/config.toml
# Set correct paths.base = "/correct/path"
```plaintext

#### Issue 2: Interpolation Failures

```bash
# Problem: {{env.VARIABLE}} not resolving
# Check environment variables
env | grep VARIABLE

# Check interpolation
provisioning validate interpolation test

# Debug interpolation
provisioning --debug validate interpolation validate
```plaintext

#### Issue 3: SOPS Encryption Errors

```bash
# Problem: Cannot decrypt SOPS files
# Check SOPS configuration
provisioning sops config

# Verify key files
ls -la ~/.config/sops/age/keys.txt

# Test decryption
sops -d encrypted-file.ncl
```plaintext

#### Issue 4: Provider Authentication

```bash
# Problem: Provider authentication failed
# Check provider configuration
provisioning show providers

# Test provider connection
provisioning provider test aws

# Verify credentials
aws configure list  # For AWS
```plaintext

### Configuration Debugging

```bash
# Show current configuration hierarchy
provisioning config show --hierarchy

# Show configuration sources
provisioning config sources

# Show interpolated values
provisioning config interpolated

# Debug specific section
provisioning config debug paths
provisioning config debug providers
```plaintext

### Configuration Reset

```bash
# Reset to defaults
provisioning config reset

# Reset specific section
provisioning config reset providers

# Backup current config before reset
provisioning config backup
```plaintext

## Advanced Configuration Patterns

### Dynamic Configuration Loading

```toml
[dynamic]
# Load configuration from external sources
config_urls = [
    "https://config.company.com/provisioning/base.toml",
    "file:///etc/provisioning/shared.toml"
]

# Conditional configuration loading
load_if_exists = [
    "./local-overrides.toml",
    "../shared/team-config.toml"
]
```plaintext

### Configuration Templating

```toml
[templates]
# Template-based configuration
base_template = "aws-web-app"
template_vars = {
    region = "us-west-2"
    instance_type = "t3.medium"
    team_name = "platform"
}

# Template inheritance
extends = ["base-web", "monitoring", "security"]
```plaintext

### Multi-Region Configuration

```toml
[regions]
primary = "us-west-2"
secondary = "us-east-1"

[regions.us-west-2]
providers.aws.region = "us-west-2"
availability_zones = ["us-west-2a", "us-west-2b", "us-west-2c"]

[regions.us-east-1]
providers.aws.region = "us-east-1"
availability_zones = ["us-east-1a", "us-east-1b", "us-east-1c"]
```plaintext

### Configuration Profiles

```toml
[profiles]
active = "development"

[profiles.development]
debug.enabled = true
providers.default = "local"
cost_controls.enabled = false

[profiles.staging]
debug.enabled = true
providers.default = "aws"
cost_controls.max_budget = 1000.00

[profiles.production]
debug.enabled = false
providers.default = "aws"
security.strict_mode = true
```plaintext

## Configuration Management Best Practices

### 1. Version Control

```bash
# Track configuration changes
git add provisioning.toml
git commit -m "feat(config): add production settings"

# Use branches for configuration experiments
git checkout -b config/new-provider
```plaintext

### 2. Documentation

```toml
# Document your configuration choices
[paths]
# Using custom base path for team shared installation
base = "/opt/team-provisioning"

[debug]
# Debug enabled for troubleshooting infrastructure issues
enabled = true
log_level = "debug"  # Temporary while debugging network problems
```plaintext

### 3. Validation

```bash
# Always validate before committing
provisioning validate config
git add . && git commit -m "update config"
```plaintext

### 4. Backup

```bash
# Regular configuration backups
provisioning config export --format yaml > config-backup-$(date +%Y%m%d).yaml

# Automated backup script
echo '0 2 * * * provisioning config export > ~/backups/config-$(date +\%Y\%m\%d).yaml' | crontab -
```plaintext

### 5. Security

- Never commit sensitive values in plain text
- Use SOPS for encrypting secrets
- Rotate encryption keys regularly
- Audit configuration access

```bash
# Encrypt sensitive configuration
sops -e settings.ncl > settings.encrypted.ncl

# Audit configuration changes
git log -p -- provisioning.toml
```plaintext

## Configuration Migration

### Migrating from Environment Variables

```bash
# Old: Environment variables
export PROVISIONING_DEBUG=true
export PROVISIONING_PROVIDER=aws

# New: Configuration file
[debug]
enabled = true

[providers]
default = "aws"
```plaintext

### Upgrading Configuration Format

```bash
# Check for configuration updates needed
provisioning config check-version

# Migrate to new format
provisioning config migrate --from 1.0 --to 2.0

# Validate migrated configuration
provisioning validate config
```plaintext

## Next Steps

Now that you understand the configuration system:

1. **Create your user configuration**: `provisioning init config`
2. **Set up environment-specific configs** for your workflow
3. **Learn CLI commands**: [CLI Reference](cli-reference.md)
4. **Practice with examples**: [Examples and Tutorials](examples/)
5. **Troubleshoot issues**: [Troubleshooting Guide](troubleshooting-guide.md)

You now have complete control over how provisioning behaves in your environment!
