miércoles, 23 de marzo de 2022

Jekyll, Hugo, static site generators y otras petisoperias


El los últimos meses hemos visto como varios bloggers han cambiado de plataforma, bien saliendo de plataformas hospedadas por terceros (blogger por ejemplo), bien de instalaciones Wordpress hosteadas por ellos mismos.

Los motivos son varios, pero podríamos resumirlos en tres:

  • Abandono de la plataforma, algo que sucede en gran medida con blogger. Da la sensación de ser un proyecto que Google mantiene al ralentí, y ya sabemos que Google no duda un momento en cerrar servicios.

  • Propiedad de los contenidos: ¿Qué pasa si una plataforma cierra de un día para otro? ¿recuperaré mis contenidos? Mentiría si dijese que tengo un backup de todas mis entradas. En general el contenido lo tengo, pero sin formato, quizás sin imágenes, etc… ¡sería un desastre!

    Además podríamos hablar (no lo haré ahora) del "efecto Medium", una plataforma que cambió su modelo de negocio, pasando a cobrar a los lectores.

  • Dificultad de mantenimiento: esto aplica principalmente a Wordpress. Nunca he hecho nada serio con él, pero si he escuchado quejas al respecto, y no pocas. Cuando el río suena…

¿Dónde han ido esos bloggers?


Parece que el uso de generadores de sitios estáticos se ha impuesto (Hugo, Jekyll, Gatsby), alojando dichos sitios principalmente en GitHub Pages, aunque esta no es la única opción; podríamos hostear en Azure Storage, en GitLab Pages, también usando Azure Static Web Apps... hay muchas opciones válidas.

Hay mucha información al respecto, aquí os dejo unos enlaces:


Algunas de las ventajas son muy claras y directas: propiedad 100% del blog, cuyo código estará alojado en un repositorio Git de tu propiedad, con todos los beneficios que esto trae, como el control de versiones y la posibilidad de ejecutar pipelines para para diversas tareas (cross posting como ejemplo).

Por otro lado, el performance del site será buenísimo, difícilmente un motor dinámico puede competir con un sitio estático.


¿Y yo qué voy a hacer? ¿Voy a seguir en Blogger?


M apetece moverme, pero echo la vista atrás y veo que no he logrado publicar regularmente. Debo empezar a publicar con regularidad de nuevo, y si lo consigo, haré el movimiento. Hacerlo al revés me parece un error.

Por lo pronto me pongo a escribir la siguiente entrada, sobre git y mis problemas por usar múltiples cuentas. 

¿Y que es eso de las petisoperías?

 
Si has leido Superlopez, seguro que lo recuerdas
 

 

lunes, 7 de febrero de 2022

Feature flags o deployment rings. ¿Por qué no ambos?

DevOps nos permite entregar valor al negocio de un modo sostenido, obteniendo feedback de producción de un modo temprano, de modo que nuestras decisiones sean tomadas en base a datos objetivos.

 

Entregar features rápido no implica que todas estas features resulten siempre satisfactorias para nuestros usuarios o el negocio. Algunas pueden fallar (tener bugs) o pese a funcionar correctamente, no resultar útiles o cómodas a nuestros usuarios, generando rechazo.

 

En esos casos, una exposición progresiva (Progressive exposure) de estas nuevas features puede reducir el rechazo, o al menos que este se produzca en un número reducido de usuarios, en vez de en toda nuestra base de clientes.

 

El conjunto de usuarios a los que llega una nueva feature se conoce como Radius blast, por analogía con el radio de expansión de una bomba. Si decimos que incrementamos el Radius blast, estaremos haciendo que una feature llegue a más usuarios.



Feature flags y Deployment rings


Dos de las técnicas más extendidas que podemos usar para exponer nuestras features progresivamete a nuestros usuarios son el uso de feature flags y la estrategia de despligue en anillos (deployment rings).

 

Ambas cumplen el propósito, pero como no podía ser de otro modo, presentan pros y contras, que debemos conocer antes de "lanzarnos" a seleccionar una.


Deployment rings


Fueron descritos por primera vez por Jez Humble en el famosísimo libro "Continuous Delivery", donde se hablaba también de canary deployments, que podemos considerar un caso especial de despliegue en anillos.

 

Portada del libro Continuous Delivery

 

 

Se trata de disponer de varios entornos de producción, siendo cada uno de tus usuarios siempre enrutado al mismo entorno, por criterios variados (geográficos, por tipo de usuario, por antigüedad u otros).

 

Cuando se despliega una nueva feature, inicialmente solo estará disponible en el primero de los entornos (anillo), donde será visible solo para un porcentaje de usuarios (los redirigidos allí).

 

A partir de ese momento comenzaremos a monitorizar activamente el comportamiento de esta nueva feature en ese primer anillo, para pasado un tiempo razonable, decidir si la progresamos al siguiente anillo (hemos ganado suficiente confianza) o bien es necesario algún cambio en el software, y por tanto un nuevo despliegue al primer anillo.

 

Este mismo proceso lo realizaremos para cada uno de los anillos que hayamos definido. Podemos verlo en el siguiente gráfico:


Proceso de CI/CD con deployment rings


 

Como veis se han definido 3 anillos: al primero lo llaman "Canaries", el siguiente es para "Early adopters" y el último engloba al resto de usuarios. A modo de ejemplo, y para una aplicación tipo "Spotify" podríamos definirlos así:

 

  • Canaries: trabajadores de Spotify
  • Early adopters: Clientes que han indicado que quieren recibir versiones "beta"
  • Users: resto de usuarios

 

Podríamos definirlo de otro modo, con más o menos anillos y usando otros criterios como decía antes, pero lo importante es el proceso, que paso a detallar:

 

  1. Un commit llega a la rama principal
  2. Se dispara atomáticamente el pipeline de CI/CD
    1. Se compila, se pasan los tests y se empaqueta el software
    2. Se despliega en el primer anillo
  3. Se monitoriza activamente durante un tiempo definido
    1. Si se encuentra algun problema, se descarta la release y no será progresada a siguientes anillos
    2. Si no se encuentran problemas, se progresa la release al siguiente anillo. Podría ser con una acción de aprobación manual o de modo automático (cuando termina el tiempo definido)
  4. Se actúa igual en los siguientes anillos

 

Como vemos ganamos en confianza a coste de ser más lentos haciendo llegar las nuevas features a nuestros usuarios.


¿Qué herramientas podemos usar para implementar una estrategia de despliegue en anillos?

 

Sin duda mis favoritas son GitHub actions y Azure Pipelines, aunque podríamos usar otras como CircleCI, Jenkins o GitLab

 

En GitHub actions nos será muy útil usar environments (aunque solo están presentes en la versión Enterprise):

https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment


En Azure DevOps Pipelines, también nos apoyaremos en los environments, y además  disponemos de las Gates, que nos pueden ayudar a monitorizar nuestra release en un anillo para decidir si progresa al siguiente:

https://docs.microsoft.com/en-us/azure/devops/pipelines/release/approvals/

 

 

Feature flags (o feature toggles)

 

Fueron descritos por primera vez por Martin Fowler en este artículo y nos permiten desacoplar la exposición  progresiva de features del despliegue de una release. Para ello, las nuevas features van controladas con un toggle, que nos permite, en tiempo de ejecución, elegir si se encuentran activas o no, y por tanto modificar el comportamiento de nuestro software.

 


 

Es decir, podemos desplegar una release con varias features desactivadas, para más adelante activarlas poco a poco, monitorizando en todo momento su comportamiento.

 

 

¿Qué necesitamos para esto?

 

  1. Un servicio de gestión de toggles.
  2. Una query que pregunte en tiempo de ejecución el valor de un toggle
  3. Una remificación if-else (o algo más sofisticado) en nuestro código que haga que el software se comporte de distinta manera cuando el toggle esté o no activado.

 

¿Qué herramientas podemos usar?


Azure App Configuration nos ofrece una gestión simple de Feature toggles, que puede servir en algunos escenarios, pero lo más seguro es que rápidamente necesites algo más avanzado, como Xabaril Esquio (un paquete para .NET hecho por algunos amigos) o un servicio como LaunchDarkly.


¿Qué opción elegir?

 

Como siempre que se hacen este tipo de preguntas, sería temerario responder categóricamente, un "depende" siempre es más acertado.

 

En ambos casos vamos a controlar qué usuarios reciben features, para después ir exponiéndolas progresivamente a otros grupos de usuarios o la totalidad de estos. Además ambas opciones nos van a permitir realizar un A/B testing controlado.

 

No obstante hay algunas diferencias importantes que debemos conocer. 

 

Coste


Con Deployment rings vamos a necesitar varios entornos de producción, mientras que con Feature flags vamos a necesitar una herramienta para controlarlas (con un store para persistir las toggles), además de cambios en nuestro código para gestionarlas.

 

Para mí este último detalle es importante. Mantener muchas toggles no es gratis, tu código se ve afectado, y las toggles deben ser eliminadas una vez que hemos decidido que una feature nunca más será desactivada.

 

La deuda de toggles puede ser peligrosa, y debemos tener en cuenta que no se trata solo de borrar la toggle, sino la ramificación de código asociada. Por aquí hablan de ello: https://codescene.com/blog/feature-toggles-are-technical-debt/


Gestión del Radius Blast

 

Podemos pensar que es más sencilla con los Deployment rings, ya que se trata de enrutar a los usuarios al entorno adecuado según los hayamos categorizado (canaries, early adopter o usuario general en el ejemplo que presentaba).

 

Sin embargo las librerías y los servicios avanzados nos permiten definir grupos de usuarios y conseguir efectos similares con toggles.

 

Además las Feature toggles nos "regalan" un rollback sencillo: si una feature no funciona podemos desactivarla al momento.

 

Confianza


La confianza es algo importante para mi, siempre digo que quiero dormir por las noches. Con Feature toggles, lo normal es que tengas un único entorno productivo, por lo que cuando despliegas una release, esta va a todos los usuarios, aunque para algunos haya features desactivadas.

 

Si una release es "mala", a veces eso pasa :-(, y su problema no está tras una feature toggle, todos los usuarios lo sufrirán.

 

Sin embargo, con Deployment rings, solo los usuarios del primer anillo "sufrirían" esa "mala" release. 

 

Habilidades del equipo y aspectos organizativos

 

Diría que la opción de las Feature toggles es más cercana al desarrollo, mientras que los Deployment rings están más cerca de la infraestructura. Las habilidades de tu equipo o la organización de tu empresa pueden determinar la decisión.


¿Podemos usar ámbas opciones simultaneamente?

 

Claro, y en algunos casos será la opción más acertada :-)

 

Continuaré con estos temas en otros posts, espero que sean de interés.


Actualización:


Me indica Vicenç García que en Uber han hecho su propia herramienta para manejar esa deuda asociada a las Feature flags. ¡Gracias!


Introducing Piranha: An Open Source Tool to Automatically Delete Stale Code - Uber Engineering Blog

domingo, 23 de mayo de 2021

Conceptos: Deploy vs Release

Hola a todos,

 

hoy vengo a hablar de dos conceptos importantes, que a veces confundimos: Deploy y release.

 

¿Son lo mismo? ¿Podemos usarlos indistintamente? ¿Siempre que despliego estoy "releaseando"? ¿Necesito necesariamente desplegar para hacer release de nuevas características en mi software?

 

Vamos a entender ambos conceptos y responder a esas preguntas, y para ello comencemos por el primero, "Deploy".


Deploy

 

Deploy es el acto técnico de hacer que un software sea "copiado" a un entorno, y pueda ser utilizado por los usuarios.

 

El mecanismo que usemos para desplegar va a diferir bastante según la tecnología que usemos para nuestra aplicación: no desplegamos igual si nuestra aplicación funciona en Azure App Service (hay que copiar ficheros a

/home/site/wwwroot) o si se ejecuta en un cluster de kubernetes (desplegaríamos subiendo una imagen a un container registry y después dando una instrucción al cluster para usarla).

 

Por otro lado, el despliegue puede ser con parada o sin ella. En el primer caso la aplicación dejará de estar disponible por un tiempo (a poder ser el mínimo posible), mientras que en el segundo (despliegue sin parada) la aplicación estará siempre disponible a los usuarios mientras es actualizada con una nueva versión.

 

Aquí te dejo un enlace a una sesión donde explico técnicas para conseguir despliegues sin parada: Despliega como los grandes: zero downtime deployment.


Release

 

Se trata de hacer que una nueva característica (feature) de la aplicación esté disponible a los usuarios.

 

¿Cómo podemos hacer que una aplicación disponga de una nueva característica? La respuesta parece sencilla: desplegando una nueva versión del software que habilite esa nueva feature.

 

Sin embargo hay más modos, esa nueva feature puede ser "activada" en un momento dado, habiendo estado oculta por un tiempo. Para ello podemos por ejemplo hacer uso de Feature flags, para activar y desactivar features. Y lo que es mejor, puede ser el negocio el que lo haga, sin necesitar conocimiento técnico.

 

Escribiré sobre Feature flags, mientras tanto te dejo este post de Luis Fraile con algunas ideas.


Respondiendo a las preguntas

 

Una vez explicados los conceptos podemos responder a las preguntas anteriores

 

¿Podemos hablar indistintamente de Deploy y de Release?

 

No, como decía el despliegue es una práctica técnica (copiar nuevos bytes para que se ejecuten), mientras que la release es un concepto de negocio, que entrega nuevas features a los usuarios.

 

¿Siempre que despliego estoy "releaseando"?

 

No tiene por qué, podría desplegar una nueva versión que por ejemplo llevase nuevo código (clases), pero que aún no son usadas.

¿Y por qué querría hacer esto? Se escapa del ámbito de este post, de nuevo hablaré sobre ello, mientras tanto te dejo esta sesión de Edu Ferro donde lo entenderás:

 

#SDsummit -  "S3 Small Safe Steps. El secreto de la agilidad", Eduardo Ferro

 

¿Necesito necesariamente desplegar para hacer release de nuevas características en mi software?

 

No, de hecho podemos ofrecer una nueva feature a nuestros clientes, habiéndola desplegado en el pasado y habiéndola mantenido oculta durante un tiempo.


Bola extra: Delivery

 

Ahora que hemos visto la diferencia entre Deploy y Release, añado un nuevo concepto íntimamente relacionado con Agile: Delivery.

 

Uno de los principios del manifiesto ágil dice: "Our highest priority is to satisfy the customer through early and continuous delivery of valuable software"

 

Se habla de entrega (delivery) de software de valor al cliente, pero ¿cómo entregamos valor a un cliente?

 

Con nuevas releases de software, pero también desplegando nuevas versiones de software que aún no entreguen nuevas features, pero que por ejemplo vayan preparando el software para la llegada de dichas features, o que como decíamos, las lleven ocultas.

 

Pero también podemos entregar valor de otros modos, totalmente ajenos al código de nuestra aplicación: Piensa que podríamos entregar valor activando un sistema de telemetría, que permitiese a negocio tomar decisiones… interesante.

 

Hasta aquí mis ideas sobre estos conceptos importantes, ¿estás de acuerdo? ¿quieres matizar algo? 

¡No dudes en comentar aquí o en twitter!

 

Saludos