Módulo 4: Policy As Code With Conftest
3. Manos a la obra: instalando `conftest`
Descripción
Esta lección tiene un solo objetivo, y es completamente ejecutado: tener conftest instalado, en tu propia máquina, con la versión confirmada por el propio binario — no por una nota en esta guía. Dos caminos, ambos $0, ambos sin cuenta ni tarjeta: el binario oficial descargado directo de GitHub Releases, o brew si usas macOS o Linux con Homebrew instalado. Vas a ver el resultado literal de ambos, y vas a terminar la lección con conftest --version devolviendo 0.69.0 o superior en tu propia terminal.
Conexión con el módulo
Esta es la primera lección de todo el módulo (y una de las pocas de toda esta guía) que no depende de LocalStack, de una cuenta, ni de ningún emulador — solo de tu máquina y de la red para descargar un binario. A partir de aquí, cada lección que sigue asume que conftest responde cuando lo invocas; esta lección es la que hace esa asunción verdadera.
Paso 1 — Camino A: el binario oficial desde GitHub Releases
Este es el camino que no depende de tener Homebrew instalado, y funciona igual en cualquier sistema con curl y tar. conftest publica un release para cada versión, con un .tar.gz distinto por sistema operativo y arquitectura:
curl -sL -o conftest.tar.gz \
https://github.com/open-policy-agent/conftest/releases/download/v0.69.0/conftest_0.69.0_Darwin_arm64.tar.gz
tar -xzf conftest.tar.gz conftest
chmod +x conftest
Tres comandos, cada uno con un trabajo concreto: curl descarga el archivo comprimido exacto de la versión 0.69.0 para macOS en Apple Silicon (Darwin_arm64) — si tu máquina es Linux x86_64 o Windows, el nombre del archivo cambia, pero el patrón conftest_<versión>_<SO>_<arquitectura>.tar.gz es siempre el mismo, listado completo en la página de releases del proyecto; tar extrae únicamente el binario conftest del archivo; chmod +x lo marca como ejecutable, un paso que Linux y macOS exigen para cualquier binario descargado directamente (a diferencia de un paquete instalado por un gestor, que ya lo deja listo).
Qué esperar (literal, ejecutado para escribir esta lección):
conftest: Mach-O 64-bit executable arm64
Esa línea es la salida del comando file conftest — confirma que lo que descargaste es un ejecutable real para tu arquitectura, no una página de error HTML disfrazada de .tar.gz (un problema real y común cuando una URL de descarga cambia sin avisar).
Paso 2 — Camino B: Homebrew, si ya lo tienes
Si tu máquina tiene Homebrew instalado, el camino es una sola línea:
brew install conftest
Antes de instalarlo, puedes confirmar qué versión te va a dar brew con brew info:
brew info conftest
Qué esperar (literal, ejecutado para escribir esta lección):
==> conftest: stable 0.69.0 (bottled), HEAD
Test your configuration files using Open Policy Agent
https://www.conftest.dev/
stable 0.69.0 — la misma versión exacta que el Camino A, empaquetada por Homebrew en vez de descargada directo del release. Cualquiera de los dos caminos te deja en el mismo punto: un binario conftest en tu PATH, versión 0.69.0.
Paso 3 — Si usaste el Camino A: moviendo el binario a tu PATH
brew install deja el binario listo para invocar desde cualquier directorio, porque Homebrew ya lo coloca en una carpeta que tu shell conoce. El binario descargado a mano en el Camino A no — vive donde lo descargaste, y conftest --version solo funciona si estás parado exactamente en esa carpeta, o si le das la ruta completa. Para que funcione desde cualquier lugar, exactamente como cualquier otro comando de tu terminal, muévelo a una carpeta que ya esté en tu PATH:
sudo mv conftest /usr/local/bin/conftest
/usr/local/bin/ es, en macOS y en la mayoría de distribuciones de Linux, una carpeta estándar para binarios instalados manualmente — ya está en el PATH por defecto, así que no hace falta editar ningún archivo de configuración del shell (.zshrc, .bashrc) para este paso específico. El sudo es necesario porque /usr/local/bin/ normalmente pertenece al usuario administrador del sistema, no a tu usuario regular.
which conftest
Qué esperar (literal, con el binario ya movido):
/usr/local/bin/conftest
Si tu instalación fue por Homebrew (Camino B), este mismo comando ya apuntaría a algo como /opt/homebrew/bin/conftest (Apple Silicon) o /usr/local/bin/conftest (Intel) desde el primer momento — Homebrew resuelve este paso por ti como parte de la instalación.
Paso 4 — La verificación que de verdad importa: conftest --version
Sin importar qué camino usaste, este es el único comando que confirma que la instalación funcionó, y con qué versión exacta vas a trabajar el resto de este módulo:
conftest --version
Qué esperar (literal, ejecutado para escribir esta lección):
Conftest: 0.69.0
OPA: 1.19.0
Dos números, no uno, y los dos importan. Conftest: 0.69.0 es la versión de la herramienta que instalaste — la misma que verificó el diseño de esta guía como la más reciente publicada al momento de escribirla. OPA: 1.19.0 es la versión del motor de Open Policy Agent que conftest trae empaquetado por dentro — no es un detalle de trivia: es la versión exacta la que decide qué sintaxis de Rego acepta tu instalación, y la lección 4 te va a mostrar por qué eso importa de inmediato, con un error real que vas a ver antes de tu primera política exitosa.
Profundización: por qué la versión exacta importa aquí, más que en la mayoría de herramientas
En muchas herramientas de línea de comandos, la versión exacta es un detalle menor —git 2.43 y git 2.45 se comportan casi idénticos para el trabajo diario—. conftest/OPA no es uno de esos casos, por una razón concreta que vas a comprobar en la próxima lección: la sintaxis de Rego que el motor acepta por defecto cambió entre versiones — específicamente, las versiones actuales del motor (a partir de OPA 1.x, la línea que conftest 0.69.0 empaqueta) exigen palabras clave (if, contains) que versiones anteriores no requerían. Una política escrita para una versión de OPA anterior a la 1.x, copiada sin cambios en una máquina con conftest 0.69.0, no compila — no falla en silencio, falla con un error de sintaxis explícito, que vas a ver literal en la lección 4. Confirmar conftest --version al principio de este módulo no es solo un ritual de instalación: es la razón exacta por la que cada política de este módulo usa la sintaxis que sí funciona contra el motor que acabas de instalar.
Errores comunes
Descargar el .tar.gz para la arquitectura equivocada (de Intel en vez de Apple Silicon, o viceversa). Qué pasa: alguien en una Mac con chip Apple Silicon (M1/M2/M3/M4) descarga por error el archivo Darwin_x86_64 en vez de Darwin_arm64 (o al revés, en una Mac Intel). Cómo detectarlo: file conftest no muestra Mach-O 64-bit executable arm64 (o x86_64) sino un error al ejecutar el binario, típicamente Bad CPU type in executable. Cómo corregirlo: confirma tu arquitectura con uname -m (arm64 para Apple Silicon, x86_64 para Intel) antes de elegir el archivo, y vuelve a descargar el correcto — no hay forma de "convertir" un binario ya descargado a la arquitectura equivocada.
Olvidar chmod +x después de extraer el binario del Camino A (de permisos). Qué pasa: alguien extrae el .tar.gz con tar y corre ./conftest --version de inmediato, sin el paso de chmod. Cómo detectarlo: el shell responde Permission denied, no un error de conftest — el sistema operativo ni siquiera llegó a intentar ejecutar el binario. Cómo corregirlo: chmod +x conftest antes de la primera ejecución; este paso es específico de binarios descargados manualmente — un instalador de paquetes como Homebrew ya lo deja resuelto.
Confundir la versión de conftest con la versión de OPA al buscar ayuda en foros o documentación (de lectura). Qué pasa: alguien busca un problema de sintaxis de Rego usando "conftest 0.69" como término de búsqueda, sin encontrar nada relevante, porque el comportamiento del lenguaje lo define la versión de OPA empaquetada (1.19.0), no la de conftest en sí. Cómo detectarlo: si tu búsqueda sobre un error de sintaxis Rego no menciona la palabra OPA en ningún resultado útil. Cómo corregirlo: conftest --version te da ambos números por esta razón exacta — para dudas de sintaxis de Rego, la versión que importa es la de OPA; para dudas de cómo conftest carga archivos o reporta resultados, la que importa es la de conftest mismo.
Ejercicios
Ejercicio 1 — Corre conftest --version en tu propia máquina y confirma los dos números. Sin copiar el resultado de esta lección, instala conftest con el camino que prefieras y confirma que tu propia terminal devuelve Conftest: 0.69.0 (o superior) y algún número de versión de OPA. Si tu versión es distinta a 0.69.0, ¿qué deberías esperar que cambie en el resto de este módulo?
Ver solución
Si tu versión es superior a 0.69.0 (por ejemplo, una versión publicada después de que se escribió esta guía), lo razonable es esperar que la sintaxis de Rego de este módulo (con if y contains) siga funcionando sin cambios — OPA mantiene compatibilidad hacia adelante dentro de la misma línea mayor (1.x) salvo que la documentación oficial de un release específico indique lo contrario. Si tu versión fuera inferior —algo intencional, por ejemplo fijando una versión anterior en un pipeline de CI—, sí podrías necesitar la sintaxis antigua (deny[msg] { ... }, sin if/contains) en vez de la que usa este módulo; la lección 4 te muestra exactamente el error que verías si mezclas ambas.
Ejercicio 2 — Explica por qué conftest --version devuelve dos números, no uno, a un compañero que nunca usó la herramienta. En dos o tres frases, explica qué representa cada número y por qué el segundo (OPA) importa tanto como el primero para el trabajo de este módulo.
Ver solución
Una explicación razonable: "conftest es una capa delgada sobre un motor más grande, llamado OPA (Open Policy Agent) — el primer número (Conftest: 0.69.0) es la versión de esa capa, la que decide cómo se cargan archivos y cómo se reportan resultados. El segundo número (OPA: 1.19.0) es la versión del motor que de verdad interpreta las reglas Rego que escribes — es ese número, no el de conftest, el que decide qué sintaxis de Rego acepta tu instalación. Confundir ambos números es la razón más común por la que alguien busca ayuda para un error de sintaxis usando el término equivocado."
Ejercicio 3 — Decide qué camino de instalación usarías en un pipeline de CI/CD, y por qué. Basándote en lo que ya sabes de cicd-and-gitops-on-aws-guide (workflows de GitHub Actions corriendo bajo act), ¿cuál de los dos caminos de esta lección (binario directo, o brew) elegirías para instalar conftest dentro de un job de CI, y qué argumento usarías para justificarlo?
Ver solución
El binario directo (Camino A) es, casi siempre, la elección correcta para CI: es más rápido (sin el overhead de resolver dependencias de un gestor de paquetes), más determinista (fijas la URL exacta de una versión exacta, sin depender de qué versión tenga cacheada el runner de Homebrew ese día), y no depende de que la imagen base del job tenga Homebrew instalado —muchas imágenes de CI minimalistas no lo traen—. brew es más cómodo para una máquina de desarrollo personal, donde ya tienes Homebrew instalado por otras razones y te conviene que brew upgrade mantenga conftest al día automáticamente; en un pipeline, esa misma actualización automática es, en realidad, un riesgo —quieres fijar una versión exacta, no la que sea "la más reciente ese día".
Resumen y siguiente paso
En esta lección instalaste conftest de verdad, con dos caminos alternativos —el binario directo de GitHub Releases, o Homebrew—, y confirmaste, con tu propia terminal, la versión exacta del motor: Conftest: 0.69.0, OPA: 1.19.0. Entendiste por qué esta versión importa más de lo habitual: define qué sintaxis de Rego acepta tu instalación, un detalle que la próxima lección convierte en un error real, visto en vivo, antes de tu primera política exitosa.
Antes de avanzar deberías poder: instalar conftest desde cero en una máquina nueva, con cualquiera de los dos caminos; explicar la diferencia entre la versión de conftest y la de OPA; y tener conftest --version respondiendo 0.69.0 o superior en tu propia terminal, ahora mismo.
La lección 4 usa esta instalación por primera vez: una política Rego trivial, un YAML de prueba, y los dos resultados —PASS y FAIL— vistos en la salida real del motor que acabas de instalar.
Recursos
- Conftest — Install — la página oficial con los binarios de cada sistema operativo y arquitectura, la fuente del Camino A de esta lección.
- GitHub —
open-policy-agent/conftest, Releases — el listado completo de versiones publicadas, incluida lav0.69.0usada en esta lección. - Homebrew — fórmula
conftest— la fórmula exacta que instala el Camino B de esta lección. - Este módulo, lección 1 — la tabla de honestidad que confirma por qué este módulo no necesita LocalStack para ninguna de sus ocho lecciones.