Skip to content

EPIC: Refactor Ansible Templates to Variables Pattern #19

@josecelano

Description

@josecelano

EPIC: Refactor Ansible Templates to Variables Pattern

Type: EPIC
Parent Epic: #16 - Finish ConfigureCommand - System Security Configuration
Depends On: #18 - Configure UFW Firewall

Overview

This epic tracks the refactoring of Ansible templates to use a centralized variables pattern similar to OpenTofu's variables.tfvars.tera approach. This consolidates multiple Tera templates into a single variables file, reducing complexity and establishing a consistent pattern for future Ansible template additions.

After implementing the security updates and firewall configuration, we now have 2 Tera templates (inventory.yml.tera and configure-firewall.yml.tera). This refactoring consolidates them into a single variables-based approach that will simplify future service additions.

Sub-Tasks

This EPIC uses vertical slice approach - each sub-task is a complete, independently deployable increment:

Goals

  • Centralized Variables: Create single variables.yml.tera for all Ansible variables
  • Template Consolidation: Reduce template complexity through variables pattern
  • Consistent Pattern: Match OpenTofu's elegant variables approach
  • Future-Proofing: Establish pattern for easy addition of new services
  • Reduced Complexity: Minimize Rust template handling boilerplate (~500 lines removed)
  • Maintain Functionality: Ensure all existing functionality continues to work

Implementation Approach

This epic uses vertical slice methodology - each sub-task is a complete, independently deployable increment that includes implementation, cleanup, documentation, and validation. This follows lean/agile principles rather than waterfall phases.

Vertical Slice 1: Create Variables Template Infrastructure (Estimated: 2.5 days)

Complete increment including:

  • Create templates/ansible/variables.yml.tera template file
  • Implement AnsibleVariablesContext with validation
  • Implement AnsibleVariablesTemplate wrapper
  • Implement VariablesTemplateRenderer orchestrator
  • Integrate into AnsibleTemplateRenderer workflow
  • Write unit tests for all components
  • Add Rustdoc documentation
  • Verify with linters and tests

Outcome: System works with new variables infrastructure in place, fully tested and documented.

See: Issue #105

Vertical Slice 2: Convert Firewall to Variables Pattern (Estimated: 4.5 days)

Complete increment including:

  • Convert configure-firewall.yml.teraconfigure-firewall.yml (static)
  • Add vars_files: [variables.yml] to playbook
  • Register as static template in copy_static_templates()
  • Update AnsibleClient to accept extra arguments
  • Update all call sites
  • Remove firewall renderer from workflow
  • Delete old firewall renderer/wrapper code (~500 lines)
  • Update template system architecture documentation
  • Update contributing templates guide
  • Update templates README
  • Run full test suite (unit, config, linters)
  • Verify build directory structure
  • Document E2E test plan for human reviewer

Outcome: System works with firewall using variables pattern, old code removed, documentation updated, all tests passing.

See: Issue #106

Total Estimated Time: 7 days (2.5 + 4.5)

Dependencies

High-Level Architecture Changes

Before Refactoring

Current Architecture (2 Tera templates + per-template infrastructure):

templates/ansible/
  ├── inventory.yml.tera              (Tera: connection details)
  └── configure-firewall.yml.tera     (Tera: with ssh_port variable)

src/infrastructure/.../ansible/template/
  ├── wrappers/
  │   ├── inventory/
  │   │   ├── mod.rs                  (InventoryTemplate wrapper)
  │   │   └── context.rs              (InventoryContext)
  │   └── firewall_playbook/          (~150 lines)
  │       ├── mod.rs                  (FirewallPlaybookTemplate wrapper)
  │       └── context.rs              (FirewallPlaybookContext)
  └── renderer/
      ├── inventory.rs                (InventoryTemplateRenderer)
      └── firewall_playbook.rs        (~350 lines - dedicated renderer)

After Refactoring

New Architecture (2 Tera templates + centralized variables):

templates/ansible/
  ├── inventory.yml.tera              (Tera: connection details - UNCHANGED)
  ├── variables.yml.tera              (Tera: NEW - centralized system variables)
  └── configure-firewall.yml          (Static: uses vars_files)

src/infrastructure/.../ansible/template/
  ├── wrappers/
  │   ├── inventory/
  │   │   ├── mod.rs                  (InventoryTemplate wrapper - UNCHANGED)
  │   │   └── context.rs              (InventoryContext - UNCHANGED)
  │   └── variables/                  (NEW ~150 lines)
  │       ├── mod.rs                  (AnsibleVariablesTemplate wrapper)
  │       └── context.rs              (AnsibleVariablesContext)
  └── renderer/
      ├── inventory.rs                (InventoryTemplateRenderer - UNCHANGED)
      └── variables.rs                (NEW ~200 lines - VariablesTemplateRenderer)

[DELETED: ~500 lines]
  - wrappers/firewall_playbook/ directory
  - renderer/firewall_playbook.rs file

Key Changes

  • Added: variables.yml.tera template + supporting Rust infrastructure (~350 lines)
  • Converted: configure-firewall.yml.tera → static configure-firewall.yml (no rendering needed)
  • Deleted: Firewall playbook renderer and wrapper (~500 lines)
  • Net Result: ~150 lines less code, simpler architecture

Acceptance Criteria

Architecture

  • Variables Template Created: templates/ansible/variables.yml.tera exists with system configuration variables
  • Firewall Template Converted: configure-firewall.yml is static (no .tera extension) and uses vars_files
  • Inventory Template Unchanged: inventory.yml.tera remains as Tera template (inventory limitation)
  • Old Components Removed: firewall_playbook renderer and wrapper deleted (~500 lines)
  • AnsibleClient Enhanced: Accepts optional extra arguments for passing variables file

Functionality

  • Functionality Preserved: All existing Ansible functionality continues to work
  • Variables Loaded: Playbooks correctly load variables from variables.yml via -e @variables.yml
  • Firewall Configuration: UFW firewall configures correctly using centralized variables
  • SSH Access Maintained: SSH connectivity preserved throughout deployment
  • Pattern Established: Clear pattern documented for adding future service variables

Code Quality

  • Tests Pass: All unit tests pass (cargo test)
  • Config Tests Pass: E2E configuration tests pass (cargo run --bin e2e-config-tests)
  • Linters Pass: All linters pass (cargo run --bin linter all)
  • No Compilation Errors: Project compiles without warnings or errors
  • Test Coverage: Comprehensive tests for AnsibleVariablesContext, AnsibleVariablesTemplate, and VariablesTemplateRenderer

Documentation

  • Architecture Doc Updated: docs/technical/template-system-architecture.md documents the variables pattern
  • Contributing Guide Updated: docs/contributing/templates.md explains how to use centralized variables
  • Templates README Updated: templates/ansible/README.md documents the variables pattern

Benefits

Architectural Consistency

  • Matches OpenTofu's successful variables.tfvars.tera pattern
  • Consistent approach to variable management across infrastructure tools
  • Single source of truth for environment-specific values

Reduced Complexity

  • Only 1 Tera template instead of multiple
  • Less Rust boilerplate for template handling
  • Simpler debugging and maintenance

Future-Proofing

  • Easy pattern for adding new services (just add variables, write static playbook)
  • Scalable approach for the full roadmap implementation
  • Clear separation of concerns (variables vs. logic)

Developer Experience

  • Easier to understand variable flow
  • Centralized variable management
  • Reduced cognitive overhead when adding new features

Related Documentation

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions