Read in English · Lire en français · Auf Deutsch lesen
Sección 10.3 de 10.8 · Intermedio · 20 min de lectura
La aplicación de doce factores y los principios nativos de la nube
Videolección
5 min · narrado en inglés, con subtítulosSolo escuchar (audio)
Leer la transcripción
Kubernetes y todas las plataformas modernas dan por supuesto que las aplicaciones se comportan de ciertas maneras. En esta lección aprenderás esas reglas, los doce factores, y cómo auditar un servicio real frente a ellas.
Piensa en una cadena de cocinas de comida para llevar. Una buena ficha de receta sirve en cualquier sucursal: enumera todos los ingredientes y no dice nada sobre la sucursal en la que está. Cualquier cocinero puede retomarla a mitad de turno, porque nada importante se guarda en la cabeza de un solo cocinero. Y cuando cambia la carta, se imprime una ficha nueva y numerada, en lugar de garabatear sobre la anterior. La aplicación de doce factores es ese tipo de ficha de receta para el software.
En 2011, Adam Wiggins, cofundador de Heroku, publicó The Twelve-Factor App, que destilaba lo que su equipo había aprendido al observar un número muy grande de aplicaciones en su plataforma. Es anterior a Docker y a Kubernetes, y aun así describe casi exactamente el contrato que esas plataformas impusieron después. Y trata de la relación de una aplicación con su plataforma, no de sus entrañas: un monolito modular puede cumplir perfectamente los doce factores.
Veamos los factores por grupos. Factor uno: un único código base en control de versiones, desplegado en muchos entornos. Factor dos: todas las dependencias declaradas, para que las compilaciones sean reproducibles en cualquier máquina. Los factores tres y cuatro mantienen las URL, las credenciales y los servicios de respaldo fuera del código, localizados mediante la configuración. Una prueba sencilla: ¿podría hacerse público hoy el código sin exponer ni una sola credencial? El factor cinco, build, release, run, mantiene separadas esas etapas. Volveremos a él en un momento. Del seis al nueve hacen seguro el escalado. Los procesos no tienen estado y no comparten nada. La aplicación da servicio escuchando en un puerto. Se escala ejecutando más procesos de cada tipo. Y los procesos arrancan rápido y se detienen de forma ordenada. Del diez al doce reducen las sorpresas: mantén parecidos el desarrollo y la producción, escribe los logs como un flujo en la salida estándar y ejecuta las tareas puntuales, como las migraciones, como procesos separados que usan la misma versión.
Este es el factor cinco. La etapa de construcción convierte un commit en un artefacto ejecutable, hoy normalmente una imagen de contenedor identificada por su digest. Se compila una sola vez. La etapa de lanzamiento combina esa imagen con la configuración de un entorno y da al resultado una identidad, como la versión cuarenta y dos. La etapa de ejecución arranca procesos a partir de una versión. Las versiones son inmutables: cualquier cambio de código o de configuración produce una versión nueva, nunca una edición de una antigua. Así que hacer rollback significa simplemente volver a ejecutar la versión cuarenta y uno, sin recompilar. Nadie edita archivos en un servidor, así que los servidores no derivan, y lo que superó las pruebas es exactamente lo que se ejecuta.
Auditemos un servicio real: el servicio de alta de restaurantes de la plataforma de reparto de comida, de cinco años de antigüedad, en dos máquinas virtuales configuradas a mano. El equipo quiere trasladarlo a la plataforma de contenedores, y la auditoría encuentra nueve problemas. Primero, la contraseña de la base de datos de producción está en un archivo del repositorio. Cualquiera que pueda leer el código la tiene. Rótala ya y trasládala al gestor de secretos. Prioridad uno. Segundo, las cartas y los logotipos subidos se escriben en el disco local de una máquina. Desaparecen cuando una solicitud llega a la otra máquina, y bloquean cualquier paso a contenedores desechables. También prioridad uno. Tercero, las sesiones se guardan en memoria, así que cada despliegue cierra la sesión del personal del restaurante a mitad de un formulario. Prioridad dos. También lo son desplegar entrando en cada máquina y descargando el código, las migraciones que ejecutan ambas instancias al arrancar y las eliminaciones forzadas durante los despliegues: sin rollback, migraciones que compiten y formularios guardados a medias. Los archivos de log, un trabajo nocturno en una sola máquina y SQLite en las computadoras portátiles de los desarrolladores pueden venir después, con prioridad tres. Fíjate en el orden: primero el riesgo, porque una credencial expuesta es un incidente en curso, después lo que bloquea la plataforma de destino, luego la fiabilidad y por último la comodidad.
Algunos consejos han envejecido. Las variables de entorno se filtran a los logs, a los informes de fallos y a los procesos hijos, así que hoy los secretos deben estar en un gestor de secretos o, mejor aún, sustituirse por la identidad de carga de trabajo, con la que la plataforma da a cada servicio credenciales de corta duración. Sin estado no significa que el sistema no tenga estado. Significa que los procesos no lo guardan: el estado se traslada a servicios de respaldo diseñados para guardarlo. Y la práctica actual añade cuatro temas: diseñar para que te eliminen en cualquier momento, no parchear nunca lo que está en ejecución, emitir logs, métricas y trazas, e incorporar la seguridad desde el principio.
La sección completa incluye una tabla con los doce factores y sus matices actuales, y la auditoría completa. A continuación, en la Sección diez punto cuatro, aplicaremos la misma disciplina a la propia infraestructura. Nos vemos allí.
Lo que necesitas saber
- The Twelve-Factor App (Adam Wiggins, Heroku, 2011, liberada como código abierto en 2024) describe el contrato entre una aplicación y una plataforma moderna, y se aplica por igual a monolitos y a microservicios.
- La configuración (III) y los servicios de respaldo (IV) mantienen fuera del artefacto todo lo que varía entre despliegues, de modo que un único artefacto se ejecuta en todos los entornos; hoy los secretos deben estar en un gestor de secretos o sustituirse por la identidad de carga de trabajo, y no en simples variables de entorno.
- Build, release, run (V) hace que las versiones sean inmutables y estén numeradas, de modo que hacer rollback significa ejecutar una versión anterior y nadie edita un servidor en ejecución.
- Los procesos sin estado (VI), la concurrencia por tipo de proceso (VIII) y la desechabilidad (IX) son lo que hace seguros el escalado horizontal, las actualizaciones graduales y la sustitución de instancias que han fallado.
- La paridad entre desarrollo y producción (X), los logs como flujos (XI) y los procesos de administración ejecutados como procesos puntuales separados (XII) reducen las sorpresas en producción; las migraciones deben ser compatibles con el código antiguo y con el nuevo.
- Más allá de los doce factores, las aplicaciones nativas de la nube se diseñan pensando en la desechabilidad, la inmutabilidad, la observabilidad y la seguridad, y la ampliación de Hoffman de 2016 añade API primero, telemetría y autenticación y autorización.
- Una auditoría frente a los factores debe ordenar las carencias por riesgo: primero los secretos expuestos, después todo lo que bloquee la plataforma de destino, como el estado local, y luego la fiabilidad y la comodidad.
De dónde vienen los doce factores
En 2011, Adam Wiggins, cofundador de Heroku, publicó The Twelve-Factor App, un breve documento web que destilaba lo que el equipo de Heroku había aprendido al observar cómo se construía, desplegaba y escalaba en su plataforma un número muy grande de aplicaciones. La metodología de la aplicación de doce factores describe aplicaciones que se configuran a partir de pasos declarativos y automatizados, tienen un contrato limpio con la plataforma sobre la que se ejecutan para poder funcionar en cualquier lugar, mantienen el desarrollo y la producción lo bastante cerca como para permitir el despliegue continuo y pueden escalar horizontalmente sin rediseñarse.
El documento es anterior a Docker (2013) y a Kubernetes (2014), y aun así describe casi exactamente el contrato que esas plataformas impusieron después: una aplicación es un conjunto de procesos sin estado, compilados en un artefacto inmutable, configurados desde fuera, que escriben sus logs en un flujo y se comunican con todo lo demás por la red. Por eso sigue siendo el vocabulario común del diseño de aplicaciones nativas de la nube. En noviembre de 2024, Heroku anunció que la metodología pasaba a ser de código abierto, mantenida por una comunidad de colaboradores de varias empresas, con el objetivo de actualizarla a la práctica actual; sus doce factores originales siguen siendo el punto de referencia.
Los factores tratan de la relación de la aplicación con su plataforma de ejecución, no de su arquitectura interna. Un monolito modular puede cumplir perfectamente los doce factores; un conjunto de microservicios puede incumplirlos todos. Complementan las inquietudes de desplegabilidad y operabilidad del Capítulo 2 y los principios de escalado y ausencia de estado del Capítulo 9.
Los doce factores, con matices actuales
| Factor | Qué significa | Por qué importa | Matiz actual |
|---|---|---|---|
| I. Código base | Un único código base en control de versiones por aplicación, desplegado en muchos entornos. | Todos los entornos ejecutan alguna versión del mismo código; no hay bifurcaciones por cliente ni por entorno. | Un monorrepo con varias aplicaciones está bien si cada aplicación tiene un límite claro; el antipatrón son las bifurcaciones de copiar y modificar. |
| II. Dependencias | Declara explícitamente cada dependencia y aísla la aplicación del sistema anfitrión. | Las compilaciones son reproducibles en cualquier máquina; nada depende de un paquete que alguien instaló a mano. | Los lockfiles y las imágenes lo convierten en lo habitual; las dependencias fijadas siguen necesitando actualizaciones periódicas y análisis de vulnerabilidades. |
| III. Configuración | Mantén todo lo que varía entre despliegues (URL, credenciales, ajustes de funcionalidades) fuera del código, en el entorno. | Un único artefacto se ejecuta en todos los entornos; los secretos nunca entran en el repositorio. | Las variables de entorno se filtran a los logs, a los informes de fallos y a los procesos hijos; es mejor leer los secretos de un gestor de secretos o de archivos montados. |
| IV. Servicios de respaldo | Trata las bases de datos, las colas, las cachés y las API externas como recursos conectados que se localizan mediante la configuración. | Una base de datos local puede sustituirse por una gestionada, o una que ha fallado por una copia restaurada, cambiando una URL. | Los cambios rara vez son transparentes cuando la semántica difiere; aísla las diferencias detrás de puertos y adaptadores. |
| V. Build, release, run | Separa la compilación de un artefacto, su combinación con la configuración para formar una versión y su ejecución. | Las versiones son inmutables y están numeradas; cualquier versión puede volver a ejecutarse; nadie edita código en un servidor. | Hoy: compila una vez en CI, guarda la imagen por su digest y registra las versiones en Git o en la herramienta de despliegue. |
| VI. Procesos | Ejecuta la aplicación como uno o varios procesos sin estado que no comparten nada; guarda el estado en servicios de respaldo. | Cualquier copia puede atender cualquier solicitud, así que las copias pueden añadirse, quitarse y sustituirse libremente. | Las sesiones persistentes (sticky sessions) ocultan el problema en lugar de resolverlo; el disco local es solo un área de trabajo temporal. |
| VII. Asignación de puertos | La aplicación es autónoma y expone su servicio escuchando en un puerto. | La plataforma le dirige el tráfico sin tener que inyectarla en un servidor web aparte. | Hoy es universal; los consumidores de colas no tienen puerto, y una service mesh puede situarse delante. |
| VIII. Concurrencia | Escala horizontalmente ejecutando más procesos, con distintos tipos de proceso para distintos trabajos (web, worker). | Cada tipo de trabajo escala de forma independiente según su propia carga. | Los autoescaladores lo hacen automáticamente, incluso según la longitud de la cola; los hilos dentro de un proceso siguen importando. |
| IX. Desechabilidad | Arranca rápido, detente de forma ordenada al recibir SIGTERM, sobrevive a una muerte repentina. | Escalado rápido, despliegues graduales seguros y robustez frente a caídas. | Los entornos de ejecución que arrancan despacio necesitan sondas de arranque (startup probes) o técnicas de arranque más rápido; los trabajos en segundo plano deben ser idempotentes y reanudables. |
| X. Paridad entre desarrollo y producción | Mantén el desarrollo, staging y producción tan parecidos como sea posible en tiempo, personas y herramientas. | Menos sorpresas que solo aparecen en producción; el despliegue continuo se vuelve seguro. | La paridad total es demasiado costosa; prioriza los mismos tipos y versiones de servicios de respaldo, usando contenedores en local. |
| XI. Logs | Escribe los logs como un flujo de eventos sin búfer en la salida estándar; deja que la plataforma los encamine. | La aplicación no gestiona archivos; los logs de todas las copias se recogen de forma centralizada. | Usa logs estructurados además de métricas y trazas (por ejemplo, mediante OpenTelemetry); vigila el volumen y el costo de los logs. |
| XII. Procesos de administración | Ejecuta las tareas puntuales (migraciones, scripts) como procesos separados que usan el mismo código y la misma configuración. | Las tareas de administración se ejecutan exactamente sobre la versión que está en producción, no sobre una copia desactualizada. | Ejecútalas como pasos del pipeline o como Jobs de Kubernetes; nunca dejes que todas las réplicas ejecuten migraciones al arrancar sin un bloqueo. |
Configuración, secretos y servicios de respaldo
El factor de configuración tiene una prueba sencilla: ¿podría hacerse público hoy el código base sin exponer ni una sola credencial? Si no es así, la configuración se ha filtrado al código. Separar la configuración del código permite que un único artefacto pase sin cambios por todos los entornos, que es la base del principio de compilar una vez de la Sección 10.5 (CI/CD y despliegue). La configuración incluye las URL de las bases de datos y de los servicios, las credenciales y los ajustes de cada entorno; excluye el cableado interno que es igual en todas partes, como qué clase atiende qué ruta, que pertenece al código.
La recomendación original de usar variables de entorno ha envejecido de forma desigual. Son universales y neutrales respecto al lenguaje, y Kubernetes, las plataformas PaaS y las funciones las admiten. Pero el entorno de un proceso es visible para sus procesos hijos, a menudo se vuelca en los informes de fallos y en las páginas de depuración, y no puede rotarse sin reiniciar. La práctica actual para los secretos es obtenerlos al arrancar de un gestor de secretos (AWS Secrets Manager, Azure Key Vault, Google Secret Manager, HashiCorp Vault u OpenBao) o montarlos como archivos que la plataforma puede actualizar y, mejor aún, sustituir los secretos de larga duración por la identidad de carga de trabajo, con la que la plataforma da automáticamente a cada servicio credenciales de corta duración. La intención del factor, mantener la configuración fuera del artefacto, no ha cambiado.
Tratar un servicio de respaldo como un recurso conectado significa que el código llega a la base de datos de pedidos, al proveedor de pagos y al intermediario de mensajes de la misma manera: mediante una URL y unas credenciales suministradas en el momento del despliegue. Eso hace que los entornos sean componibles y que la recuperación sea más rápida. No hace que los servicios de respaldo sean intercambiables por arte de magia; sustituir un intermediario de mensajes por otro cambia la semántica de entrega. El estilo hexagonal del Capítulo 5 complementa el factor: la configuración dice dónde está el recurso, y un adaptador detrás de un puerto oculta cómo se comporta.
Build, release, run (construcción, lanzamiento, ejecución)
El factor build, release, run (construcción, lanzamiento, ejecución) separa tres etapas que a menudo se confunden. La etapa de construcción (build) convierte un commit en un artefacto ejecutable, hoy normalmente una imagen de contenedor identificada por su digest. La etapa de lanzamiento (release) combina ese artefacto con la configuración de un entorno y da al resultado una identidad, como la versión v42 del servicio de pedidos en producción. La etapa de ejecución (run) arranca procesos a partir de una versión. Las versiones son inmutables: un cambio de código o de configuración produce una versión nueva, nunca una edición de una existente.
Compilar una vez, lanzar por entorno, ejecutar en cualquier lugar
Esta separación es lo que hace que desplegar sea aburrido. Nadie edita archivos en un servidor, así que los servidores no derivan; la misma imagen que superó las pruebas en staging se ejecuta en producción, así que un resultado de prueba significa algo; y el rollback es una operación rápida y ensayada en lugar de una recompilación de emergencia. También es una pista de auditoría: para cualquier momento puedes decir exactamente qué código y qué configuración se estaban ejecutando. Kubernetes guarda un historial de revisiones de los ReplicaSets de cada Deployment, las plataformas PaaS numeran las versiones y GitOps (Sección 10.4) convierte el historial de Git del repositorio de versiones en el registro.
Procesos, concurrencia y desechabilidad
Los procesos sin estado que no comparten nada son la condición previa de casi todo lo demás en este capítulo: el escalado horizontal, los despliegues graduales, el autoescalado, la sustitución de nodos que han fallado y la distribución entre zonas. Todo lo que un proceso guarda solo en su memoria o en su disco local (la sesión de un usuario, un archivo subido, un informe a medio generar) se pierde cuando se sustituye ese proceso, y es invisible para las demás copias. El Capítulo 9 trata en detalle la gestión de sesiones (balanceo de carga, ausencia de estado y sesiones). El estado no desaparece; se traslada a servicios de respaldo diseñados para guardarlo.
El factor de concurrencia añade que los distintos tipos de trabajo deben ejecutarse como distintos tipos de proceso que escalan por separado. En la plataforma de reparto de comida, el proceso web que atiende la app del cliente escala según la tasa de solicitudes, mientras que un proceso worker que envía las confirmaciones de pedido escala según la longitud de la cola, y un consumidor de ubicaciones de los repartidores, según el throughput de eventos. Mezclarlos en un solo tipo de proceso obliga a escalarlos todos por las necesidades de uno.
La desechabilidad exige que los procesos arranquen en segundos y se detengan limpiamente. Al recibir SIGTERM, un proceso web deja de aceptar conexiones y termina las solicitudes en curso; un worker devuelve su mensaje actual a la cola o lo termina dentro del periodo de gracia. Como los procesos también pueden morir sin aviso (un fallo de nodo, una eliminación por falta de memoria), el trabajo debe poder repetirse sin peligro: un tratamiento idempotente de los mensajes, como en la arquitectura dirigida por eventos, y trabajos que se reanudan desde puntos de control. George Candea y Armando Fox llevaron la idea al límite en 2003 con el software crash-only, que tiene una sola forma de detenerse (caerse) y una sola forma de arrancar (recuperarse), de modo que la ruta de recuperación se ejercita constantemente en lugar de descubrirse durante un incidente.
Paridad entre desarrollo y producción, logs y procesos de administración
El texto original identifica tres brechas entre desarrollo y producción: el tiempo (código escrito semanas antes de desplegarse), las personas (los desarrolladores lo escriben, los operadores lo despliegan) y las herramientas (SQLite en una computadora portátil, PostgreSQL en producción). La entrega continua cierra la primera, los equipos que operan lo que construyen cierran la segunda y los contenedores cierran buena parte de la tercera: un desarrollador puede ejecutar en local la misma versión de PostgreSQL, el mismo intermediario de mensajes y la misma caché, y herramientas como Testcontainers arrancan dependencias reales en las pruebas de integración. La paridad perfecta no es ni asequible ni necesaria; lo que más importa es usar los mismos tipos y versiones de servicios de respaldo, porque ahí es donde viven las diferencias que sorprenden.
Los logs como flujos de eventos significan que la aplicación escribe cada evento en la salida estándar y deja el almacenamiento, la rotación y el envío a la plataforma. Eso sigue siendo correcto, con dos añadidos actuales: los logs deben ser estructurados (por ejemplo, JSON con nombres de campo coherentes y un identificador de solicitud o de traza), y los logs son una de las tres señales, junto con las métricas y las trazas, que hacen observable un sistema (observabilidad). El volumen de logs es también un factor de costo real; la Sección 10.8 vuelve sobre ello.
Los procesos de administración, como las migraciones de bases de datos, las reparaciones de datos y los informes puntuales, deben ejecutarse con la misma versión (código y configuración) que la aplicación, como procesos separados. En Kubernetes eso suele significar un Job que el pipeline ejecuta antes de desplegar la nueva versión. Las migraciones requieren un cuidado especial: deben ser compatibles tanto con la versión antigua como con la nueva del código, que se ejecutan en paralelo, que es la disciplina de expandir y contraer de la evolución de esquemas.
Más allá de los doce factores
Los doce factores nunca pretendieron ser completos, y autores posteriores los ampliaron. Beyond the Twelve-Factor App (O'Reilly, 2016), de Kevin Hoffman, revisó la lista hasta quince, añadiendo API primero (diseñar el contrato antes que la implementación), telemetría (incorporar métricas, estado de salud y trazado) y autenticación y autorización (la seguridad como inquietud de diseño desde el principio). La práctica actual añade cuatro temas que toda aplicación nativa de la nube debería cumplir.
Desechabilidad, en serio. Diseña para que te eliminen en cualquier momento: operaciones idempotentes, timeouts de solicitud cortos, tiempo de arranque acotado, drenaje ordenado y ningún proceso cuya pérdida importe. Inmutabilidad. Nunca parchees un contenedor o un servidor en ejecución; compila una imagen nueva y sustitúyelo (Sección 10.4, sobre la infraestructura inmutable). Así cada instancia en ejecución puede rastrearse hasta un commit y desaparece la deriva. Observabilidad. Emite logs estructurados, métricas y trazas mediante un estándar como OpenTelemetry, expón endpoints de estado que reflejen el estado del propio proceso y propaga el contexto de traza entre llamadas, para que los operadores puedan responder preguntas que no habían previsto. Seguridad. Ejecuta como usuario sin privilegios de root con un sistema de archivos de solo lectura siempre que sea posible; obtén las credenciales mediante la identidad de carga de trabajo en lugar de claves de larga duración; aplica el mínimo privilegio a cada servicio de respaldo; y compila a partir de imágenes mínimas, analizadas y firmadas (seguridad de la cadena de suministro).
Ejemplo práctico
Ejemplo práctico: auditoría del servicio de alta de restaurantes
El servicio de alta de restaurantes de la plataforma de reparto de comida es una aplicación web de cinco años que se ejecuta en dos máquinas virtuales configuradas a mano detrás de un balanceador de carga con sesiones persistentes. El equipo quiere trasladarlo a la plataforma de contenedores de la empresa. Una auditoría frente a los factores encuentra nueve problemas; a cada uno se le asigna un riesgo, una solución y una prioridad.
| 1. Contraseña de la base de datos de producción en un archivo de propiedades del repositorio (III) | Riesgo: cualquiera con acceso de lectura al código, incluidos antiguos contratistas, tiene la credencial. Solución: rotar la contraseña ya, trasladarla al gestor de secretos e inyectarla en el momento del despliegue. Prioridad 1. |
|---|---|
| 2. Cartas y logotipos subidos que se escriben en el disco local de la VM (VI, IV) | Riesgo: los archivos desaparecen cuando una solicitud llega a la otra VM o cuando se sustituye una VM; bloquea cualquier paso a contenedores desechables. Solución: almacenamiento de objetos, con una copia puntual de los archivos existentes. Prioridad 1. |
| 3. Sesiones en la memoria del proceso, balanceo de carga persistente (VI) | Riesgo: cada despliegue cierra la sesión del personal del restaurante a mitad de un formulario. Solución: tokens de sesión firmados o un almacén de sesiones compartido. Prioridad 2. |
4. Despliegue por SSH, git pull y reinicio en cada VM (V, II) | Riesgo: las dos VM ejecutan código distinto tras un pull fallido; no hay rollback. Solución: CI compila una imagen por commit; versiones numeradas. Prioridad 2. |
| 5. Migraciones que ambas instancias ejecutan automáticamente al arrancar (XII) | Riesgo: dos instancias compiten por la misma migración. Solución: un paso de migración separado en el pipeline, con cambios de expandir y contraer. Prioridad 2 (Prioridad 1 si ya se ha producido una carrera). |
6. Procesos eliminados con kill -9 durante los despliegues (IX) | Riesgo: formularios de alta guardados a medias. Solución: tratar SIGTERM, drenar las solicitudes, añadir readiness y un retardo previo a la detención (pre-stop). Prioridad 2. |
| 7. Logs escritos en archivos rotativos en cada VM (XI) | Riesgo: los logs se pierden con la VM; es difícil buscar entre instancias. Solución: JSON estructurado en la salida estándar, recogido de forma centralizada. Prioridad 3, barato de hacer junto con el punto 4. |
| 8. Informe nocturno de pagos a restaurantes como entrada de cron solo en la VM 1 (XII, VIII) | Riesgo: el trabajo deja de ejecutarse sin avisar cuando se reconstruye la VM 1, o se ejecuta dos veces si se copia. Solución: un trabajo programado en la plataforma, hecho idempotente. Prioridad 3. |
| 9. Los desarrolladores usan SQLite y producción usa PostgreSQL (X) | Riesgo: SQL que funciona en local falla en producción. Solución: PostgreSQL en un contenedor para desarrollo y pruebas. Prioridad 3. |
Las prioridades siguen primero al riesgo (una credencial expuesta es un incidente en curso), después a lo que bloquea la plataforma de destino (el estado local), luego a la fiabilidad y por último a la comodidad.
El equipo no necesita arreglarlo todo antes de migrar: los puntos 1 y 2 son requisitos previos; los puntos 3 a 6 pueden hacerse durante el traslado; los puntos 7 a 9 pueden venir después.
Una auditoría como esta es también un buen material para un registro de decisiones de arquitectura: explica por qué se hace cada cambio, en qué orden y qué se ha aplazado deliberadamente.
Preguntas frecuentes
¿Toda aplicación necesita cumplir los doce factores?
No. Son una lista de comprobación de propiedades que abaratan el despliegue, el escalado y la recuperación en una plataforma moderna. Trata cada carencia como un riesgo con un costo, y corrige primero las que bloquean tu plataforma o amenazan la seguridad, como en la auditoría anterior.
¿Se aplica la metodología a las funciones serverless?
En gran medida, y la plataforma impone la mayor parte: las funciones no tienen estado, se configuran desde fuera, son desechables y la plataforma registra sus logs. Los factores que siguen necesitando atención son la configuración y los secretos, los servicios de respaldo, la idempotencia y la paridad entre desarrollo y producción, ya que la emulación local de las fuentes de eventos de un proveedor es imperfecta.
¿Siguen siendo relevantes los doce factores ahora que existe Kubernetes?
Sí, porque Kubernetes los da por supuestos. Un pod que guarda sesiones en memoria, escribe archivos en local o tarda dos minutos en arrancar choca con las actualizaciones graduales, el autoescalado y la reprogramación de la plataforma. Los factores describen lo que una aplicación debe hacer para que la automatización de la plataforma ayude en lugar de perjudicar.
Comprueba lo que has entendido
¿Qué prueba sencilla muestra si la configuración se ha filtrado al código?
Pregúntate si el código base podría hacerse público hoy sin exponer ninguna credencial. Si no, la configuración (al menos los secretos) vive en el código.
¿Por qué build, release, run hace que el rollback sea rápido?
Cada versión es una combinación inmutable de un artefacto compilado y una configuración, con su propia identidad, así que hacer rollback significa volver a ejecutar la versión anterior, sin recompilar ni editar nada.
Un servicio guarda los archivos subidos en el disco local de su servidor. ¿Qué factor incumple y qué se rompe?
Procesos (VI) y, se puede argumentar, servicios de respaldo (IV): los archivos faltan cuando las solicitudes llegan a otra copia y se pierden cuando se sustituye la instancia, lo que bloquea el escalado horizontal y los contenedores desechables.
¿Por qué no deben ejecutarse las migraciones automáticamente en cada réplica al arrancar?
Varias réplicas pueden ejecutar la misma migración a la vez y competir entre sí, y el arranque se vuelve lento y frágil. Las migraciones deben ejecutarse una sola vez, como un paso de administración separado en el pipeline, usando la misma versión.
Fuentes y lecturas recomendadas
¿Tienes una pregunta sobre esta sección? ArchitectBot, el asistente de estudio con IA del curso, responde primero a partir del curso.
Pregunta: “¿Qué carencias respecto a los doce factores deberíamos corregir antes de trasladar un servicio antiguo a Kubernetes, y cuáles pueden esperar?”