# πŸ”— ValidaciΓ³n Multi-Capas: KCL β†’ Terraform β†’ Ansible **Fecha**: 2025-11-20 **ClasificaciΓ³n**: Estrategia de validaciΓ³n end-to-end **Enfoque**: Aprovechar validaciones nativas de cada herramienta --- ## πŸ“‹ Tabla de Contenidos 1. [Arquitectura Multi-Capas](#arquitectura-multi-capas) 2. [ValidaciΓ³n KCL (Definitions)](#validaciΓ³n-kcl-definitions) 3. [ValidaciΓ³n Terraform (IaC)](#validaciΓ³n-terraform-iac) 4. [ValidaciΓ³n Ansible (Configuration)](#validaciΓ³n-ansible-configuration) 5. [OrquestaciΓ³n NuShell](#orquestaciΓ³n-nushell) 6. [Flujos de ValidaciΓ³n End-to-End](#flujos-de-validaciΓ³n-end-to-end) --- ## πŸ—οΈ Arquitectura Multi-Capas ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ CAPA 0: DEFINICIONES (KCL) β”‚ β”‚ ═══════════════════════════════════════════════════════ β”‚ β”‚ β€’ services.k (definiciones de servicios) β”‚ β”‚ β€’ patterns.k (patrones de despliegue) β”‚ β”‚ β€’ policies.k (polΓ­ticas de validaciΓ³n) β”‚ β”‚ β”‚ β”‚ VALIDACIΓ“N: kcl compile β”‚ β”‚ βœ… Tipos correctos β”‚ β”‚ βœ… Sin ciclos de dependencias β”‚ β”‚ βœ… Referencias vΓ‘lidas β”‚ β”‚ βœ… Esquema completo β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ↓ (genera) β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ CAPA 1: INFRAESTRUCTURA AS CODE (Terraform) β”‚ β”‚ ═══════════════════════════════════════════════════════ β”‚ β”‚ β€’ kubernetes.tf (generado desde KCL) β”‚ β”‚ β€’ docker-compose.tf (generado desde KCL) β”‚ β”‚ β€’ networking.tf (generado desde KCL) β”‚ β”‚ β€’ variables.tf (configuraciΓ³n) β”‚ β”‚ β”‚ β”‚ VALIDACIΓ“N: terraform validate β”‚ β”‚ βœ… Sintaxis HCL correcta β”‚ β”‚ βœ… Recursos vΓ‘lidos β”‚ β”‚ βœ… Dependencias de recursos β”‚ β”‚ βœ… Variables requeridas β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ↓ (planifica) β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ CAPA 2: PLAN DE INFRASTRUCTURE (Terraform Plan) β”‚ β”‚ ═══════════════════════════════════════════════════════ β”‚ β”‚ β€’ terraform.tfplan (plan de cambios) β”‚ β”‚ β€’ impacto en recursos β”‚ β”‚ β€’ dependencias detectadas β”‚ β”‚ β”‚ β”‚ VALIDACIΓ“N: terraform plan -json β”‚ β”‚ βœ… Cambios permitidos β”‚ β”‚ βœ… Sin errores de aplicaciΓ³n β”‚ β”‚ βœ… Impacto predecible β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ↓ (genera) β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ CAPA 3: CONFIGURACIΓ“N (Ansible) β”‚ β”‚ ═══════════════════════════════════════════════════════ β”‚ β”‚ β€’ site.yml (playbook principal) β”‚ β”‚ β€’ roles/ β”‚ β”‚ β”œβ”€ api-server/ β”‚ β”‚ β”‚ β”œβ”€ database/ β”‚ β”‚ β”‚ └─ monitoring/ β”‚ β”‚ β€’ group_vars/ β”‚ β”‚ └─ production.yml (variables generadas) β”‚ β”‚ β”‚ β”‚ VALIDACIΓ“N: ansible-playbook --syntax-check β”‚ β”‚ βœ… Sintaxis YAML correcta β”‚ β”‚ βœ… Tasks bien formados β”‚ β”‚ βœ… Roles vΓ‘lidos β”‚ β”‚ βœ… Variables resuelven β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ↓ (genera) β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ CAPA 4: DESPLIEGUE FINAL β”‚ β”‚ ═══════════════════════════════════════════════════════ β”‚ β”‚ β€’ Infrastructure aplicada β”‚ β”‚ β€’ Servicios configurados β”‚ β”‚ β€’ Monitoreo activo β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ FLUJO: Cada capa valida su propio dominio usando herramientas nativas ``` --- ## βœ… ValidaciΓ³n KCL (Definitions) ### 1. KCL Native Validation ```bash # ValidaciΓ³n nativa - sin cΓ³digo personalizado $ kcl compile provisioning/services.k # Detecta automΓ‘ticamente: # ❌ Errores de tipo services = [ { id: 123 # ERROR: Esperaba str } ] # ❌ Campos requeridos service = { id: "api" # ERROR: name requerido } # ❌ Referencias invΓ‘lidas depends_on: ["service-inexistente"] # ERROR # ❌ Ciclos de dependencias api = { depends_on: ["db"] } db = { depends_on: ["api"] } # ERROR: CICLO # ❌ Puertos duplicados ports: [3000, 3000] # ERROR ``` ### 2. Script NuShell: Ejecutar ValidaciΓ³n KCL ```nushell #!/usr/bin/env nu # kcl-validate.nu - Validar definiciones KCL def validate_kcl [kcl_file: path] { print "πŸ” Validando KCL: $kcl_file" let result = ( kcl compile $kcl_file 2>&1 ) if ($result | str contains "Error:") { print "❌ Errores encontrados:" print $result return { success: false error: ($result | str trim) } } print "βœ… KCL vΓ‘lido" return { success: true output: $result } } # Uso validate_kcl "provisioning/services.k" ``` ### 3. QuΓ© Valida KCL AutomΓ‘ticamente ``` βœ… TIPO-SEGURIDAD └─ id: str, port: int, replicas: int └─ Rechaza valores con tipo incorrecto βœ… REQUERIMIENTOS └─ Campos obligatorios deben estar presentes └─ Rechaza estructuras incompletas βœ… CICLOS DE DEPENDENCIAS └─ FunciΓ³n validate_no_dependency_cycles en policies.k └─ Rechaza Aβ†’Bβ†’A βœ… REFERENCIAS └─ Los servicios en depends_on deben existir └─ Rechaza referencias a servicios inexistentes βœ… UNICIDAD └─ Puertos ΓΊnicos por host/namespace └─ IDs ΓΊnicos en catΓ‘logo βœ… RESTRICCIONES DE RECURSOS └─ CPU/Memory en formato vΓ‘lido (100m, 512Mi) └─ LΓ­mites >= requests βœ… RELACIONES └─ Service debe existir antes de referenciar └─ Patterns referencian servicios existentes ``` --- ## πŸ—οΈ ValidaciΓ³n Terraform (IaC) ### 1. Terraform Native Validation ```bash # ValidaciΓ³n nativa de HCL $ terraform validate # Detecta automΓ‘ticamente: # ❌ Sintaxis HCL invΓ‘lida resource "kubernetes_service" "api" { metadata { name = "api" # ERROR: bloque mal formado } } # ❌ Tipos incorrectos resource "kubernetes_deployment" "api" { spec { replicas = "2" # ERROR: Esperaba nΓΊmero } } # ❌ Variables no definidas resource "kubernetes_service" "api" { metadata { namespace = var.undefined_var # ERROR } } # ❌ Referencias invΓ‘lidas resource "kubernetes_service" "api" { spec { selector { app = kubernetes_deployment.undefined.spec.selector.match_labels.app # ERROR } } } ``` ### 2. Terraform Plan Validation ```bash # ValidaciΓ³n de plan $ terraform plan -json # Analiza: # βœ… Cambios vΓ‘lidos # βœ… Dependencias correctas # βœ… Recursos creables # ❌ Cambios destructivos # ❌ Errores de aplicaciΓ³n # ❌ Conflictos de estado ``` ### 3. Script NuShell: Validar Terraform ```nushell #!/usr/bin/env nu # terraform-validate.nu - Validar generado Terraform def validate_terraform [tf_dir: path] { print "πŸ” Validando Terraform: $tf_dir" # Cambiar a directorio cd $tf_dir # Validar sintaxis let validate_result = ( terraform validate -json 2>&1 | from json ) if not $validate_result.valid { print "❌ Errores de sintaxis Terraform:" print $validate_result return { success: false errors: $validate_result.diagnostics } } print "βœ… Sintaxis Terraform vΓ‘lida" # Validar plan let plan_result = ( terraform plan -json 2>&1 | from json ) # Buscar cambios destructivos let destructive = ( $plan_result.resource_changes | filter { |rc| $rc.change.actions | any { |a| $a == "delete" } } ) if ($destructive | length) > 0 { print "⚠️ CAMBIOS DESTRUCTIVOS DETECTADOS:" $destructive | each { |rc| print $" - ($rc.type).($rc.name) serΓ‘ eliminado" } } return { success: true plan_summary: $plan_result.summary destructive_changes: ($destructive | length) } } # Uso validate_terraform "generated/terraform" ``` ### 4. Ejemplo: Terraform Generado desde KCL ```hcl # Generado automΓ‘ticamente desde services.k variable "namespace" { type = string default = "production" } variable "docker_registry" { type = string default = "docker.io" } # Kubernetes Deployment - Generado desde service.id="api" resource "kubernetes_deployment" "api" { metadata { name = "api-server" namespace = var.namespace labels = { app = "syntaxis" component = "api" tier = "backend" } } spec { replicas = 2 # Desde service.replicas selector { match_labels = { app = "api-server" } } template { metadata { labels = { app = "api-server" } } spec { container { name = "api" image = "${var.docker_registry}/syntaxis:api-latest" # Desde service.image port { name = "http" container_port = 3000 # Desde service.port } # Recursos - Desde service.resources resources { requests = { cpu = "100m" memory = "256Mi" } limits = { cpu = "500m" memory = "512Mi" } } # Health check - Desde service.healthCheck liveness_probe { http_get { path = "/health" port = "http" } initial_delay_seconds = 10 period_seconds = 10 } # Env vars - Desde service.env env { name = "RUST_LOG" value = "info" } env { name = "DATABASE_URL" value = "postgresql://postgres:5432/syntaxis" } } # Depends on - Desde service.depends_on init_container { name = "wait-for-db" image = "${var.docker_registry}/busybox:latest" command = ["sh", "-c", "until nc -z database 5432; do sleep 1; done"] } } } } } # Kubernetes Service - Generado automΓ‘ticamente resource "kubernetes_service" "api" { metadata { name = "api-service" namespace = var.namespace } spec { selector = { app = "api-server" } port { name = "http" port = 80 target_port = "http" } type = "LoadBalancer" } } # ValidaciΓ³n que Terraform hace automΓ‘ticamente: # βœ… name es string requerido # βœ… namespace referencia variable existente # βœ… replicas es nΓΊmero (2) # βœ… image es string vΓ‘lido # βœ… port es nΓΊmero (3000) # βœ… resources.requests.cpu es formato vΓ‘lido # βœ… init_container referencias imagen vΓ‘lida # βœ… selector.app coincide con deployment.labels ``` ### 5. QuΓ© Valida Terraform AutomΓ‘ticamente ``` βœ… SINTAXIS HCL └─ Bloques, atributos, tipos correctos └─ Comillas, llaves, punto y coma βœ… TIPOS DE DATOS └─ Numbers, strings, booleans correctos └─ Listas y objetos bien formados βœ… REFERENCIAS └─ Variables referenciadas existen └─ Recursos referenciados estΓ‘n definidos └─ MΓ³dulos vΓ‘lidos βœ… DEPENDENCIAS └─ Orden de creaciΓ³n correcto └─ Ciclos detectados βœ… PROVEEDORES └─ Proveedor Kubernetes configurado └─ Versiones compatibles βœ… PLAN └─ Cambios aplicables └─ Sin conflictos de estado └─ Dependencias resuelven βœ… VALIDACIONES CUSTOMIZADAS └─ Nombre debe contener patrΓ³n └─ Replicas dentro de rango └─ CPU requests < limits ``` --- ## βš™οΈ ValidaciΓ³n Ansible (Configuration) ### 1. Ansible Native Validation ```bash # ValidaciΓ³n de sintaxis YAML $ ansible-playbook site.yml --syntax-check # Detecta automΓ‘ticamente: # ❌ YAML invΓ‘lido - hosts: all tasks: - name: Start service systemd: name: api # ERROR: indentaciΓ³n incorrecta # ❌ Tasks malformados - name: Invalid task copy: src: file.txt dest: /tmp/ # ERROR: falta 'dest' o 'src' # ❌ Roles inexistentes - import_role: name: undefined_role # ERROR: rol no existe # ❌ Variables sin resolver - name: Use variable debug: msg: "{{ undefined_var }}" # ERROR: variable no existe ``` ### 2. Script NuShell: Validar Ansible ```nushell #!/usr/bin/env nu # ansible-validate.nu - Validar playbooks Ansible def validate_ansible [playbook_file: path] { print "πŸ” Validando Ansible: $playbook_file" # Validar sintaxis let syntax_check = ( ansible-playbook $playbook_file --syntax-check 2>&1 ) if ($syntax_check | str contains "ERROR") { print "❌ Errores de sintaxis Ansible:" print $syntax_check return { success: false error: ($syntax_check | str trim) } } print "βœ… Sintaxis Ansible vΓ‘lida" # Validar roles let roles_dir = "roles" let roles = ( ls $roles_dir | get name | map { |r| $r | path basename } ) print $"πŸ“¦ Roles detectados: ($roles | str join ', ')" # Validar references en playbook let playbook_content = (open $playbook_file) for role in $roles { if not ($playbook_content | str contains $role) { print $"⚠️ Rol ($role) no utilizado" } } return { success: true roles_count: ($roles | length) roles: $roles } } # Uso validate_ansible "site.yml" ``` ### 3. Ejemplo: Playbook Generado desde KCL ```yaml # Generado automΓ‘ticamente desde services.k --- - name: Deploy syntaxis services hosts: all become: yes vars_files: - group_vars/{{ environment }}.yml vars: # Variables generadas desde KCL services: - name: api-server port: 3000 image: "{{ docker_registry }}/syntaxis:api-latest" replicas: 2 - name: database port: 5432 image: "{{ docker_registry }}/postgres:15-alpine" replicas: 1 pre_tasks: - name: Validate Docker is installed command: docker --version register: docker_version changed_when: false - name: Validate connectivity to services wait_for: host: "{{ item.host }}" port: "{{ item.port }}" timeout: 5 loop: - { host: database, port: 5432 } roles: # Generado desde service.id="api-server" - role: api-server vars: service_port: 3000 service_image: "{{ docker_registry }}/syntaxis:api-latest" service_replicas: 2 service_env: # Desde service.env RUST_LOG: info DATABASE_URL: "postgresql://postgres:5432/syntaxis" service_resources: # Desde service.resources cpu: 100m memory: 256Mi # Generado desde service.id="database" - role: database vars: service_port: 5432 service_image: "{{ docker_registry }}/postgres:15-alpine" service_replicas: 1 postgresql_databases: - name: syntaxis user: postgres post_tasks: - name: Verify all services are running uri: url: "http://api-server:3000/health" method: GET status_code: 200 retries: 3 delay: 10 ``` ### 4. QuΓ© Valida Ansible AutomΓ‘ticamente ``` βœ… SINTAXIS YAML └─ IndentaciΓ³n correcta └─ Estructura vΓ‘lida βœ… TASKS VÁLIDOS └─ Modules existen └─ ParΓ‘metros correctos └─ Handlers referencian nombres vΓ‘lidos βœ… ROLES └─ Directorio structure correcto └─ Tasks, handlers, templates presentes βœ… VARIABLES └─ Sintaxis de variable correcta {{ var }} └─ Tipos de dato correctos βœ… INVENTARIOS └─ Hosts vΓ‘lidos └─ Grupos existentes βœ… HANDLERS └─ Listeners referencian names vΓ‘lidos └─ Sin handlers huΓ©rfanos βœ… IMPORTS/INCLUDES └─ Archivos referencian existen └─ Variables presentes ``` --- ## 🎯 OrquestaciΓ³n NuShell ### 1. validate-all.nu - OrquestaciΓ³n Completa ```nushell #!/usr/bin/env nu # validate-all.nu - ValidaciΓ³n multi-capa completa const GREEN = "[32m" const RED = "[91m" const YELLOW = "[33m" const BLUE = "[34m" const RESET = "[0m" def separator [title: string] { print "" print $"($BLUE)════════════════════════════════════════($RESET)" print $"($BLUE)($title)($RESET)" print $"($BLUE)════════════════════════════════════════($RESET)" } # CAPA 0: KCL VALIDATION separator "CAPA 0: ValidaciΓ³n KCL (Definiciones)" let kcl_result = ( kcl compile "provisioning/services.k" 2>&1 ) if ($kcl_result | str contains "Error:") { print $"($RED)❌ KCL invΓ‘lido($RESET)" print $kcl_result exit 1 } else { print $"($GREEN)βœ… KCL vΓ‘lido($RESET)" print $" - Tipos correctos" print $" - Sin ciclos" print $" - Referencias vΓ‘lidas" } print "" # CAPA 1: TERRAFORM VALIDATION separator "CAPA 1: ValidaciΓ³n Terraform (IaC)" # Generar Terraform desde KCL si no existe if not (path exists "generated/terraform/main.tf") { print "πŸ“ Generando Terraform desde KCL..." # Ejecutar generador nu generate-terraform.nu } cd "generated/terraform" let tf_validate = ( terraform validate -json 2>&1 | from json ) if not $tf_validate.valid { print $"($RED)❌ Terraform invΓ‘lido($RESET)" print $tf_validate.diagnostics exit 1 } else { print $"($GREEN)βœ… Terraform vΓ‘lido($RESET)" print $" - Sintaxis HCL correcta" print $" - Variables resuelven" print $" - Recursos vΓ‘lidos" } # Plan let plan_result = ( terraform plan -json 2>&1 | from json ) # Analizar cambios let changes = ( $plan_result.resource_changes | map { |rc| {type: $rc.type, name: $rc.name, actions: $rc.change.actions} } ) print $" Plan summary:" for change in $changes { print $" - ($change.type).($change.name): ($change.actions | str join 'β†’')" } cd - # volver al directorio anterior print "" # CAPA 2: ANSIBLE VALIDATION separator "CAPA 2: ValidaciΓ³n Ansible (Configuration)" # Generar Ansible desde KCL si no existe if not (path exists "generated/ansible/site.yml") { print "πŸ“ Generando Ansible desde KCL..." # Ejecutar generador nu generate-ansible.nu } let ansible_check = ( ansible-playbook "generated/ansible/site.yml" --syntax-check 2>&1 ) if ($ansible_check | str contains "ERROR") { print $"($RED)❌ Ansible invΓ‘lido($RESET)" print $ansible_check exit 1 } else { print $"($GREEN)βœ… Ansible vΓ‘lido($RESET)" print $" - Sintaxis YAML correcta" print $" - Roles vΓ‘lidos" print $" - Variables resuelven" } print "" # RESUMEN FINAL separator "πŸ“Š RESUMEN DE VALIDACIΓ“N" print $"($GREEN)TODAS LAS CAPAS VALIDADAS EXITOSAMENTE($RESET)" print "" print "βœ… Capa 0 - KCL (Definiciones)" print "βœ… Capa 1 - Terraform (Infraestructura)" print "βœ… Capa 2 - Ansible (ConfiguraciΓ³n)" print "" print $"($GREEN)Listo para deployment($RESET)" print "" ``` ### 2. Flujo en CI/CD ```nushell # .github/workflows/validate-all.yml equivalent print "πŸš€ Iniciando validaciΓ³n multi-capas..." # 1. KCL validation if (!(kcl compile provisioning/services.k)) { print "❌ KCL failed" exit 1 } # 2. Terraform validation if (!(terraform validate)) { print "❌ Terraform failed" exit 1 } # 3. Ansible validation if (!(ansible-playbook site.yml --syntax-check)) { print "❌ Ansible failed" exit 1 } # 4. All passed print "βœ… All layers validated" ``` --- ## πŸ”„ Flujos de ValidaciΓ³n End-to-End ### Flujo 1: Cambio en Service Definition ``` Developer modifica services.k: β”œβ”€ Agrega nuevo servicio "monitoring" Git commit + push ↓ GitHub CI Pipeline (validate-all.nu): β”œβ”€ CAPA 0: kcl compile β”‚ └─ βœ… KCL vΓ‘lido β”‚ β”œβ”€ Generar Terraform desde KCL (actualizadas) β”‚ β”œβ”€ CAPA 1: terraform validate β”‚ └─ βœ… Nuevo recurso vΓ‘lido β”‚ └─ βœ… Sin conflictos β”‚ β”œβ”€ Generar Ansible desde KCL (actualizadas) β”‚ β”œβ”€ CAPA 2: ansible-playbook --syntax-check β”‚ └─ βœ… Nuevo role incorporado β”‚ └─ βœ… Variables resuelven β”‚ └─ βœ… APROBADO para merge Resultado: └─ ValidaciΓ³n hecha por herramientas nativas └─ Sin cΓ³digo personalizado de validaciΓ³n └─ Confianza en cada capa ``` ### Flujo 2: ValidaciΓ³n de Compatibilidad ``` Cambio detectado: Se rompe dependencia β”œβ”€ database β†’ service inexistente Pipeline CI: β”œβ”€ CAPA 0: kcl compile β”‚ └─ ❌ ERROR: "service-b depends on non-existent service-c" β”‚ └─ ❌ RECHAZADO inmediatamente Developer notificado: └─ Corrije el error └─ Reintenta ``` ### Flujo 3: ValidaciΓ³n de Impacto ``` Cambio: Puerto de database 5432 β†’ 5433 Pipeline CI: β”œβ”€ CAPA 0: kcl compile β”‚ └─ βœ… KCL vΓ‘lido β”‚ β”œβ”€ Generar Terraform β”‚ β”œβ”€ CAPA 1: terraform plan β”‚ └─ Detecta: "RDS port change" (breaking) β”‚ └─ ⚠️ Manual approval required β”‚ └─ ⚠️ ESPERANDO APROBACIΓ“N MANUAL DevOps revisa: └─ "Esto requiere downtime" └─ Aprueba manualmente └─ Deployment continΓΊa ``` --- ## πŸ“Š ComparaciΓ³n: ValidaciΓ³n Manual vs Multi-Capa | Aspecto | Manual | Multi-Capa (Nativo) | |---------|--------|-------------------| | **Errores de tipo KCL** | Descubiertos al deploy | Rechazados al commit | | **Sintaxis Terraform** | Descubiertos al deploy | Rechazados al commit | | **Errores Ansible** | Descubiertos al deploy | Rechazados al commit | | **Ciclos de dependencias** | Requiere revisiΓ³n manual | Detectado automΓ‘ticamente | | **Conflictos de puerto** | Requiere revisiΓ³n manual | Detectado automΓ‘ticamente | | **Cambios destructivos** | Riesgo en producciΓ³n | Detectado antes de apply | | **Tiempo de descubrimiento** | Horas (en deploy) | Segundos (en commit) | | **Costo de error** | Alto (downtime) | Bajo (cambio rechazado) | --- ## 🎯 Resumen: Cada Herramienta Valida Su Dominio ``` KCL β†’ Valida definiciones (servicios, dependencias) ↓ Terraform β†’ Valida infraestructura (HCL, recursos, plan) ↓ Ansible β†’ Valida configuraciΓ³n (playbooks, roles) ↓ NuShell β†’ Orquesta validaciΓ³n + reporta resultados ``` **Beneficio**: - βœ… Cada herramienta hace lo que sabe hacer mejor - βœ… Validaciones nativas = confiables - βœ… Sin duplicaciΓ³n de lΓ³gica - βœ… Errores descubiertos temprano (en commit, no en deploy) - βœ… Confianza en cada capa del pipeline --- ## πŸ“‹ Checklist de ImplementaciΓ³n - [ ] Crear `validate-all.nu` script principal - [ ] Crear `kcl-validate.nu` para KCL - [ ] Crear `terraform-validate.nu` para Terraform - [ ] Crear `ansible-validate.nu` para Ansible - [ ] Integrar en `.github/workflows/validate.yml` - [ ] Setup pre-commit hooks para validaciΓ³n local - [ ] Documentar flujos de validaciΓ³n para DevOps - [ ] Crear dashboard que muestre validaciones - [ ] Test con cambios vΓ‘lidos e invΓ‘lidos --- **ConclusiΓ³n**: Las herramientas modernas (KCL, Terraform, Ansible) ya incluyen validaciΓ³n nativa de sus dominios. La clave es orquestarlas inteligentemente con NuShell para crear un pipeline de validaciΓ³n completo end-to-end.