Contract-First, paralelización de desarrollo y hackeo de imágenes Docker

¡Certificados de seguridad expirados, un pipeline roto y una imagen Docker hackeada! ¿Cómo logramos superar estos obstáculos sin interrumpir el funcionamiento de la aplicación? Déjame compartirte mi experiencia personal y las soluciones que implementamos.

Haz clic aquí para ver otros casos de mis experiencias personales.

El caso

Todo comenzó cuando fuimos notificados por un proveedor que los certificados digitales que utilizaba nuestra aplicación para validar la información de los usuarios estaban por expirar en dos semanas. El backend de la aplicación estaba confirmado por dos monolitos, uno de reglas de negocio y otro de comunicaciones. En este último debía hacerse la actualización de certificados, pero su pipeline estaba roto y ya no era viable crear uno nuevo, ya que no contábamos con expertos en la tecnología que se había deprecado. Si no actualizábamos los certificados a tiempo, nuestra aplicación quedaría inutilizada, pues la validación de usuarios se realizaba al 100 % de estos.

La solución parecía ser crear tres nuevos microservicios e intervenir el backend de reglas de negocio para que consultara estos nuevos servicios y no el monolito de comunicaciones, pero no nos alcanzaría el tiempo, pues la forma de trabajar del equipo hacía que fuera necesario crear primero los microservicios para poder luego intervenir el backend. Tendríamos que encontrar entonces la forma de paralelizar el trabajo. También deberíamos tener un plan alternativo en caso de que no alcanzáramos a tener todo listo a tiempo.

La solución

Todos en el equipo, sin importar nuestros roles, estábamos divagando sobre las formas de dar solución a la situación. Finalmente, mi propuesta fue la que logró convencer a todos. Dicho plan consistía en:

  • Aplicar Contract-First para diseñar los contratos (los request y responses) de los servicios antes de iniciar el desarrollo y así poder paralelizar el trabajo. De esta forma creé mocks (con CastleMock) de los servicios del proveedor, y de cómo deberían responder los nuevos microservicios que reemplazarían las consultas al monolito de comunicaciones.
  • Entonces creamos diferentes frentes de trabajo simultáneos para intervenir el monolito de reglas de negocio y crear cada uno de los tres microservicios. La intervención en el monolito de reglas de negocio sería mínima, pues los nuevos servicios deberían responder exactamente como lo haría el monolito de comunicaciones. Se acordó postergar cualquier mejora, adaptación u optimización de las respuestas de los servicios para no poner en riesgo el plazo.
  • Mientras tanto, yo me encargué personalmente del Plan B. En este caso era tener una versión “hackeada” de la imagen Docker de producción del monolito de comunicaciones para desplegarla manualmente como contingencia. Compilar en local no era una opción, pues al no haber un pipeline no había certeza de las condiciones y variables para crear una compilación que funcionara correctamente en el ambiente productivo.

¿Como prevenimos esto?

Muchos descuidos, que impulsé o apoyé, nos llevaron a esta situación que casi termina en tragedia. Siempre es importante extraer las lecciones aprendidas de estos momentos decisivos. Para evitar estas situaciones debemos:

  • Dar prioridad a las migraciones tecnológicas a pesar de que casi no tenga frecuencia de uso. En nuestro caso, tuvimos dos:
    • El pipeline: la última vez que se hizo un paso a producción (se ejecutó el pipeline) fue tres años atrás, por eso nunca lo vimos como una urgencia.
    • El proveedor había creado hace un año unos servicios REST, que no requieren certificados, para deprecar los servicios SOAP que nosotros aún usábamos. Nunca priorizamos esto, pues creíamos que era innecesario actualizar ya que “pronto” (notar las comillas) íbamos a dejar de usar ese monolito, pero dicho cambio también se fue postergando para dar paso a nuevas necesidades (apagar incendios).
  • Tener calendarios de los vencimientos de certificados y credenciales y planes de trabajo claros para ejecutar con antelación y prevenir estas situaciones. Quizás las soluciones hubiera sido diferentes si nos hubiéramos enterado antes de estos vencimientos.
  • Intentar siempre paralelizar el trabajo mediante técnicas como Contract-First y el uso de mocks que simulen las respuestas diseñadas. De esta forma se acelera la entrega de valor, pues ya no es necesario que se cree primero un servicio para luego crear o intervenir la contraparte que lo consultará (backendfrontendState Machine u otro), una solución podría salir en un solo Sprint y no en dos o más.
  • Debe haber una política clara de documentación. Toda persona debe dejar plasmado su conocimiento bien sea en términos de código (pruebas unitarias y código de negocio), scripts o documentos como tal. Hay que aclarar que estos documentos deben intentar ser lo más sencillos posibles para alentar a la participación. Por ejemplo, en el caso del diseño de contratos de servicios, aunque se recomienda, no es necesario que se haga un OpenAPI (Swagger), un texto plano bastará.

Alguna vez escuché a MiduDev, o su invitado, decir que alcanzas tu máximo grado de Senior cuando te encuentras de nuevo con los problemas que creaste 💩, piensas “que bruto, ¿Cómo pude pensar que era una buena solución?”, reflexionas, aprendes, corriges y lo apuntas en tu libreta personal de lecciones aprendidas. Mucho ánimo y a seguir equivocándose, solo así se progresa.

Author: Alex Andrade

Magister Ingeniería de Software, MBA y Especialista en Gerencia de Proyectos Tel: +57-317-241-5118

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.