Skip to content

ADR-051: Infrastructure Simplification - KISS Principle Applied

Status: Accepted Date: 2025-10-24 Deciders: Infrastructure Team, Development Team, Architect Technical Story: Reduce infrastructure complexity by eliminating redundant files and consolidating deployment logic

Context and Problem Statement

Our infrastructure codebase has grown organically over multiple iterations, resulting in:

  1. Excessive File Count: 58 infrastructure-related files across 4 directories
  2. Redundant Implementations: Multiple versions of similar functionality (PowerShell + Bash + Bicep)
  3. Scattered Documentation: Deployment guides in 3+ locations with conflicting information
  4. Temporary Files Committed: 26 planning documents mixed with production code
  5. Duplicate Modules: Multiple Bicep modules for similar Azure resources (e.g., Container Apps that are being replaced)
  6. Complex Maintenance: Any infrastructure change requires updates to 5+ files

Current State Analysis: - Infrastructure files: 58 total - Deployment scripts: 16 (8 Bash + 8 PowerShell) - Bicep modules: 18 - Parameter files: 14 (7 dev + 7 test) - Helper scripts: 5 - Compiled ARM templates: 2 (unnecessary) - Temporary planning docs: 26 (should be in temp/ folder)

Problem Impact: - New developers struggle to find correct deployment documentation - Unclear which scripts/modules are authoritative vs experimental - Difficult to ensure consistency across Bash and PowerShell versions - High maintenance burden (single change affects many files)

Decision Drivers

  • KISS Principle: Keep It Simple, Stupid - eliminate unnecessary complexity
  • Maintainability: Reduce files that need updating for infrastructure changes
  • Developer Experience: Clear, obvious path for deployment and troubleshooting
  • Code Quality: Remove dead code, obsolete experiments, and redundant implementations
  • Documentation: Single source of truth for deployment procedures

Decision

Aggressively simplify infrastructure codebase by applying KISS principle:

1. Delete Obsolete Container Apps Files (10 files)

Why: Migrating from Container Apps to ACI, these are no longer needed:

# Bicep modules (4 files)
infrastructure/bicep/modules/container-app-api.bicep
infrastructure/bicep/modules/container-app-mcp-server.bicep
infrastructure/bicep/modules/container-app-ui.bicep
infrastructure/bicep/modules/container-platform.bicep

# Deployment scripts (4 files)
infrastructure/scripts/build-and-push-images.sh
infrastructure/scripts/build-images-in-acr.sh
infrastructure/scripts/configure-acr-developer-access.sh
infrastructure/scripts/deploy-all-layers.sh

# Parameter files (2 files)
infrastructure/bicep/environments/dev-layer4.parameters.json
infrastructure/bicep/environments/test-layer4.parameters.json

2. Delete Redundant/Superseded Files (11 files)

Why: Replaced by simpler alternatives or no longer relevant:

# VPN Gateway modules (replaced by Bastion)
infrastructure/bicep/modules/vpn-gateway.bicep
infrastructure/bicep/modules/vpn-gateway-with-azure-ad.bicep

# Private endpoint modules (consolidated into single module)
infrastructure/bicep/modules/acr-private-endpoint.bicep
infrastructure/bicep/modules/ai-foundry-private-endpoints.bicep

# Subnet delegation utility (one-time operation, no longer needed)
infrastructure/bicep/modules/subnet-delegation-update.bicep

# Helper scripts (functionality consolidated)
infrastructure/scripts/helpers/acr-build-helpers.sh
infrastructure/scripts/helpers/docker-compose-helpers.sh
infrastructure/scripts/helpers/image-build-helpers.sh
infrastructure/scripts/helpers/layer-dependency-helpers.sh
infrastructure/scripts/helpers/validation-helpers.sh

# Compiled ARM templates (never use compiled ARM, always use Bicep)
infrastructure/bicep/compiled/full-deployment.json

3. Delete Temporary Planning Documents (26 files)

Why: These should never have been committed, belong in temp/ folder:

# Planning documents (all files starting with TEMP-, PLANNING-, DRAFT-)
infrastructure/temp/TEMP-*
infrastructure/temp/PLANNING-*
docs/temp/DRAFT-*
# (see full list in migration guide documentation audit)

4. Consolidate Deployment Scripts (Prefer Bash)

Decision: Maintain ONLY Bash versions of deployment scripts - PowerShell scripts were created as alternatives, but Bash works cross-platform - Bicep CLI works identically on Windows/Linux/Mac via Bash - Reduce duplication: 16 scripts → 8 scripts (50% reduction)

Keep (Bash): - deploy-foundation.sh - deploy-substrate.sh - deploy-ai-models.sh - deploy-apps.sh - install-prerequisites.sh - teardown.sh - validate-deployment.sh - build-and-push-to-acr.sh (new, consolidates image building)

Delete (PowerShell - redundant): - deploy-foundation.ps1 - deploy-substrate.ps1 - deploy-ai-models.ps1 - deploy-apps.ps1 - install-prerequisites.ps1 - teardown.ps1 - validate-deployment.ps1

Rationale: - PowerShell works on all platforms (pwsh), but adds maintenance burden - Bicep deployment via Azure CLI is identical across platforms - Every script change requires updating 2 files (Bash + PowerShell) - Most cloud engineers are familiar with Bash (Linux heritage) - Azure Cloud Shell uses Bash by default

5. Consolidate Bicep Modules (Keep 10 Core Modules)

After cleanup, keep these essential modules:

infrastructure/bicep/modules/
  ├── networking.bicep                    # VNet, Subnets, NSGs
  ├── bastion-vm.bicep                    # Bastion + Windows Jump Box (new)
  ├── managed-identity.bicep              # System-assigned identity
  ├── log-analytics.bicep                 # Monitoring workspace
  ├── ai-services.bicep                   # AI Foundry Hub + Project
  ├── container-registry.bicep            # ACR
  ├── container-group-aci.bicep           # ACI deployment (new)
  ├── ai-model-deployment.bicep           # AI model deployments
  ├── security.bicep                      # Key Vault
  └── private-endpoints.bicep             # Generic PE module

Result: 18 modules → 10 modules (44% reduction)

6. Simplify Parameter Files (8 Files Total)

infrastructure/bicep/environments/
  ├── dev-foundation.parameters.json      # Foundation layer (dev)
  ├── dev-substrate.parameters.json       # Substrate layer (dev)
  ├── dev-ai-models.parameters.json       # AI Models layer (dev)
  ├── dev-apps.parameters.json            # Apps layer (dev)
  ├── test-foundation.parameters.json     # Foundation layer (test)
  ├── test-substrate.parameters.json      # Substrate layer (test)
  ├── test-ai-models.parameters.json      # AI Models layer (test)
  └── test-apps.parameters.json           # Apps layer (test)

Result: 14 parameter files → 8 parameter files (43% reduction)

7. Consolidate Documentation (5 Essential Docs)

Keep in docs/deployment/:

docs/deployment/
  ├── README.md                          # Overview + quick links
  ├── azure-infrastructure-guide.md      # Complete deployment guide
  ├── bastion-dev-access.md              # Dev environment access
  ├── troubleshooting.md                 # Common issues + fixes
  └── architecture-diagrams.md           # Visual reference

Delete/Archive: - Old VPN guides (superseded by Bastion) - Redundant "getting started" docs - Experiment documentation - Conflicting deployment instructions

Consequences

Positive

  1. Massive Simplification: 58 files → 25 files (57% reduction)
  2. Easier to understand system
  3. Faster onboarding for new developers
  4. Less maintenance burden

  5. Single Source of Truth: Clear, authoritative files for each concern

  6. One deployment script per layer (Bash only)
  7. One Bicep module per Azure resource type
  8. One documentation guide per topic

  9. Reduced Duplication: No more syncing Bash + PowerShell

  10. 50% reduction in deployment scripts
  11. Changes need updating in fewer places
  12. Less risk of inconsistency

  13. Clearer Intent: Removed experiments and dead code

  14. Obvious which files are production vs experimental
  15. Temporary files in temp/ folder (git-ignored)
  16. No confusion about which version to use

  17. Better Organization: Logical structure

  18. Bicep modules organized by resource type
  19. Scripts organized by deployment layer
  20. Documentation organized by user journey

  21. Faster Development: Less time navigating files

  22. Quick to find correct script/module
  23. Obvious where to make changes
  24. Faster to validate changes (fewer files to review)

Negative

  1. Loss of PowerShell Scripts: Windows-centric teams may prefer PowerShell
  2. Mitigation: Bash works on Windows via WSL, Git Bash, or PowerShell (via bash command)
  3. Mitigation: Document Bash installation for Windows developers

  4. One-Time Migration Cost: Updating references to deleted files

  5. Mitigation: Clear migration guide with exact commands
  6. Mitigation: Phased approach (test in dev before production)

  7. Potential Breaking Changes: If any code references deleted files

  8. Mitigation: Search codebase for references before deletion
  9. Mitigation: Update all documentation in same commit

  10. Loss of Historical Context: Deleting old experiments may lose insights

  11. Mitigation: Git history preserves all deleted files
  12. Mitigation: Document decisions in ADRs (like this one)

Implementation

Deletion Strategy

Phase 1: Safe Deletions (Low Risk)

# Delete temporary planning documents (never should've been committed)
git rm -r infrastructure/temp/TEMP-*
git rm -r infrastructure/temp/PLANNING-*
git rm -r docs/temp/DRAFT-*

# Delete compiled ARM templates (always use Bicep source)
git rm infrastructure/bicep/compiled/*.json

Phase 2: Container Apps Cleanup (Migrating to ACI)

# Delete Container Apps modules (replaced by ACI)
git rm infrastructure/bicep/modules/container-app-*.bicep
git rm infrastructure/bicep/modules/container-platform.bicep

# Delete Container Apps scripts (replaced by ACI scripts)
git rm infrastructure/scripts/build-and-push-images.sh
git rm infrastructure/scripts/build-images-in-acr.sh
git rm infrastructure/scripts/configure-acr-developer-access.sh
git rm infrastructure/scripts/deploy-all-layers.sh

# Delete Container Apps parameters
git rm infrastructure/bicep/environments/*-layer4.parameters.json

Phase 3: Redundant Files (Consolidating)

# Delete redundant PowerShell scripts (keeping Bash only)
git rm infrastructure/scripts/*.ps1

# Delete obsolete VPN Gateway modules (replaced by Bastion)
git rm infrastructure/bicep/modules/vpn-gateway*.bicep

# Delete redundant private endpoint modules (consolidated)
git rm infrastructure/bicep/modules/acr-private-endpoint.bicep
git rm infrastructure/bicep/modules/ai-foundry-private-endpoints.bicep

# Delete one-time subnet delegation utility
git rm infrastructure/bicep/modules/subnet-delegation-update.bicep

# Delete redundant helper scripts (functionality consolidated)
git rm infrastructure/scripts/helpers/*-helpers.sh

Phase 4: Documentation Cleanup

# Archive old deployment docs
git mv docs/deployment/old-vpn-setup.md docs/archive/vpn-setup.md
git mv docs/deployment/container-apps-guide.md docs/archive/container-apps-guide.md

# Delete redundant getting-started docs (consolidated into main guide)
git rm docs/deployment/quick-start-*.md

Validation After Deletion

Verify no broken references:

# Search for references to deleted files
grep -r "container-app-" --include="*.bicep" --include="*.sh" --include="*.md"
grep -r "vpn-gateway" --include="*.bicep" --include="*.sh" --include="*.md"
grep -r "\.ps1" --include="*.md" --include="*.sh"

# Verify deployment still works
./infrastructure/scripts/deploy-foundation.sh dev ldfdev-rg

Comparison: Before vs After

Metric Before After Reduction
Total Files 58 25 57% ⬇️
Deployment Scripts 16 (8 Bash + 8 PS) 8 (Bash only) 50% ⬇️
Bicep Modules 18 10 44% ⬇️
Parameter Files 14 8 43% ⬇️
Helper Scripts 5 0 (consolidated) 100% ⬇️
Temp Files 26 0 (deleted) 100% ⬇️
Documentation Files 12 5 58% ⬇️
Compiled ARM 2 0 (deleted) 100% ⬇️

Maintainability Impact: - Infrastructure change affecting all layers: 20+ files → 10 files (50% reduction) - Deployment script update: 2 files (Bash + PS) → 1 file (Bash only) - Documentation update: 3-5 docs → 1-2 docs (single source of truth)

KISS Principle Applied

KISS = Keep It Simple, Stupid

This ADR applies KISS to infrastructure by:

  1. Eliminating Duplication: One implementation (Bash), not two (Bash + PowerShell)
  2. Removing Dead Code: Container Apps modules no longer used
  3. Consolidating Functionality: Helper scripts merged into main deployment scripts
  4. Cleaning Up Experiments: Temporary files deleted or moved to temp/ folder
  5. Single Source of Truth: One deployment guide, not multiple conflicting versions
  6. Obvious Structure: Clear naming, logical organization, no surprises

Quote from "The Pragmatic Programmer":

"Don't live with broken windows. Fix bad designs, wrong decisions, and poor code when you see them."

This cleanup fixes accumulated "broken windows" in our infrastructure codebase.

Success Criteria

  • ✅ File count reduced by >50%
  • ✅ No broken references to deleted files
  • ✅ Deployment still works end-to-end
  • ✅ Documentation clear and up-to-date
  • ✅ New developers can find what they need quickly
  • ✅ Infrastructure changes require updating fewer files
  • Related: ADR-049 (Container Deployment - ACI vs Container Apps) - drives Container Apps file deletion
  • Related: ADR-050 (Bastion Replaces VPN Gateway) - drives VPN file deletion
  • Related: ADR-052 (Layer Renaming) - drives parameter file consolidation

References


Status: Accepted Date Accepted: 2025-10-24 Impact: High (major cleanup of infrastructure codebase)