Deployments tipo canary y cómo dormir tranquilos por las noches

Avatar img
Patricio Moreano
Tech Lead @ Kushki
septiembre 16, 2020
Lectura de 2 minutos
 Deployments tipo canary y cómo dormir tranquilos por las noches

Deployments tipo canary

Hoy te contaremos sobre una técnica donde el código desplegado a producción no se cambia al instante por el código anterior, sino en un lapso de tiempo y bajo un ambiente controlado, para permitirte dormir tranquilo por la noche.


Es muy común pensar que la única forma en que las empresas de tecnología despliegan su código en producción sea durante horas no laborables y abriendo ventanas de mantenimiento para sus clientes.

Esta es una práctica antigua adoptada por empresas grandes que, de cierta manera, funciona, pero ¿a qué costo? Al costo de tener un equipo dedicado para esos despliegues, horas extras, horarios nocturnos y significativa carga para los empleados y las empresas.

Además, al introducir nuevas funcionalidades en producción, por más pruebas que se hayan realizado (pruebas punta a punta y pruebas unitarias), siempre existe el riesgo del factor humano, pues nadie es perfecto y algo puede fallar. Por esa razón, se opta por deployar en horas no laborables. Ante estos abrumadores problemas, que muchas veces separan al desarrollador de software de su preciado sueño, llegan los deployments de tipo canary.

Los deployments tipo canary son una técnica donde el código desplegado a producción no se cambia al instante por el código anterior, sino que en un lapso de tiempo y bajo un ambiente controlado se monitorea errores, estadística y demás para reemplazar el código en su totalidad o dar rollback. Eso mi querido lector, es lo que te vengo a contar en este artículo.

Deployment canary

Deployment Canary 2

Diagrama del antes, durante y después de un deploy tipo canary.

Los deployments tipo canary nacen justamente por la necesidad y la obsesión del desarrollador de software de lograr controlar hasta el último detalle de un deploy (despliegue) a producción. A nadie le gusta meter bugs en producción, pero es algo con lo que todos los que hemos programado hemos tenido que lidiar y sabemos que no desaparecerá, pues es parte de la imperfección del ser humano. Sin embargo, lo que sí podemos hacer es reducir esos bugs al mínimo y que, si aparecen, sea solo en componentes y funcionalidades no críticas de un producto o servicio, para minimizarlos tanto en número como en impacto hacia el producto.

El deploy tipo canary consiste en introducir una nueva versión del código desarrollado y hacerlo disponible a una pequeña parte de los usuarios, e ir incrementando el número de usuarios con acceso a éste en un lapso de tiempo determinado. Así por ejemplo se puede lanzar el tipo 10percentEveryMinute, lo que significa que al primer minuto de deployado el código en producción sólo el 10% de los usuarios lo estará usando, mientras que el otro 90% restante seguirá accediendo al código antiguo. El porcentaje de uso del nuevo código se irá incrementando progresivamente hasta completar el despliegue total.

El despliegue paulatino puede venir acompañado de alarmas de monitoreo automatizadas que, si detectan que el nivel de errores en el código que está siendo puesto a prueba es mayor al threshold (umbral) permitido, se hace un rollback automático. Entendiendo como rollback a la funcionalidad de abortar el nuevo despliegue a producción, usado, generalmente, porque se encontraron errores en el código nuevo.

Igualmente, puedes complementar el monitoreo de las alarmas con funciones que corran antes y después de empezar el despliegue, esto con el fin de asegurar que el código a probar no tenga ningún problema. La idea es, poner a correr el sistema de pruebas con el código antiguo que sabemos que funciona, en una primera etapa, para luego repetir esta prueba con el código nuevo. Con esto se evita que el despliegue aleatorio, por mala suerte, haya hecho invisible algún posible bug durante el deploy por simple estadística.

De esta manera, los deploy tipo canary te permiten:

  • Realizar despliegues a producción en un ambiente controlado.

  • Mayor facilidad para hacer rollback.

  • Versionar el código en producción.

  • Reducir significativamente los bugs.

Como podemos ver, el deploy tipo canary tiene bastantes bondades bien vistas por desarrolladores al momento de lanzar código a producción, pero también quiero poner en perspectiva que si la estadística está mal leída, puede llegar a causar que se aborten deploys por resultados llenos de falsos positivos de errores que, en realidad, no ocurrieron. Pues, durante el deploy pueden presentarse problemas de proveedores o de terceros con los cuáles se está integrado, y al tener la medición de errores de forma automatizada, el deploy quedará cancelado automáticamente, tomando los problemas de estos terceros como nuestros.

Esto refuerza la necesidad de establecer más mecanismos de control, que aunque alargarán el proceso de salida a producción, reducirán en gran medida el margen de error y evitaremos caer en falsos positivos.


A continuación podrás ver un ejemplo práctico del deploy tipo canary utilizando el framework Serverless.

Podrás configurar el deploy tipo canary de una manera muy simple, en una estructura de un proyecto serverless, con las siguientes líneas de código:

El deploy tipo canary queda configurado de una manera muy simple en una estructura de un proyecto serverless con las siguientes líneas de código:

Paso 1: Instala la versión del plugin en el archivo package.json

"serverless-plugin-canary-deployments": "0.4.8" 

Paso 2: Referencia el plugin en la sección 'plugins' del archivo serverless.yml

  plugins:  
    - serverless-plugin-canary-deployments

Paso 3: Configura las opciones del canary a utilizar. En este ejemplo, especificaremos dos alarmas, los ambientes a aplicar el deploy tipo canary y el tipo.

  deploymentSettings:  
    stages:  
      - ci  
      - qa  
      - stg  
      - uat  
      - primary  
    type: 10percentEvery1Minute  
    alias: Live  
    alarms:  
      - ErrorChargesGatewayAlarm  
      - ErrorChargesCountAlarm

Paso 4: Referencia la configuración del canary deploy en la función lambda a aplicar.

  functions:  
    record:  
      handler: src/handler/RecordHandler.HANDLER  
      deploymentSettings: ${self:custom.deploymentSettings}

Y ¡listo!


Hemos analizado gran parte de los pros y contras que podemos encontrar en un deploy tipo canary, desde el concepto hasta un ejemplo práctico de cómo hacerlo funcional. Sin dudas, esta práctica se está volviendo una tendencia cada vez más utilizada en el mundo del desarrollo de software ya que minimiza errores en componentes críticos de un sistema de software, permitiendo a los desarrolladores dormir tranquilos por las noches.

Sé el alma de la fiesta con la información más fresca sobre pagos digitales.

Suscríbete a nuestro Kushki Hub para recibir alertas de nuestro nuevo contenido.

Suscribe illustration
¿No sabes qué producto es el indicado para tu comercio?
¿El mundo de los pagos llama tu atención?

Más de nuestro Kushki Hub

Trajimos el pago de suscripción por débito a Chile

¡Buenas noticias! Ahora Kushki tiene pago de suscripción por débito en Chile De acuerdo a la última Encuesta Financiera de Hogares del Banco Central, el 73% de la población chilena posee tarjetas de débito; y gracias a nuestro sistema de tokenización de estas tarjetas, los usuarios tendrán acceso a servicios digitales de streaming, transporte, delivery, etc. que funcionen con pago recurrente o suscripción. Lo que quiere decir, que la mayor parte de la población podría disfrutar de servicios como Rappi, Netflix, Didi, Amazon, entre otros, a los que anteriormente no podían acceder por no formar parte del 43% de la población que posee tarjeta de crédito. Es importante destacar, que Chile era el único país de la región donde todavía no se podía tokenizar el débito, pero en alianza con Übank, integramos un sistema para que los usuarios pudieran usar sus tarjetas para transferir ahorros desde las cuentas corrientes. Disponibilizando así una tecnología hasta ahora desconocida por el mercado chileno, que impulsará un cambio importante en la economía del país y servicio a los clientes. Esperamos que este sea solo el inicio de un avance sustancial en la inclusión de la población a servicios en línea, y que prontamente el uso de este sistema sea una regla en los métodos de pago de apps y plataformas digitales de servicios. Puedes leer la noticia original al respecto del Diario 24 Horas, aquí.
Avatar img
Stella Vargas
Líder de contenido @Kushki
septiembre 10, 2020

Impulsado el desarrollo de la industria inmobiliaria con MobySuite

Impulsando el desarrollo de la industria inmobiliaria con MobySuite Los medios digitales han marcado un hito importante en la comercialización de bienes y servicios, y la industria inmobiliaria no es una excepción. Ya las plataformas digitales eran el medio preferido para la compra y renta de propiedades, cuando el COVID-19 nos obligó a aislarnos, exacerbando la necesidad de los negocios a adoptar las nuevas tecnologías y digitalizarse. Ante esta necesidad, las empresas PropTech (Property technolgy), siguen buscando la mejor manera de aplicar la tecnología al refinamiento, mejora y reinvención del sector inmobiliario. Una de estas empresas es MobySuite, que con su software inmobiliario 100% online, asiste en el proceso de compra de una propiedad desde el primer contacto del potencial dueño hasta el momento de entrega del inmueble. Facilitando desde la atención al cliente (de forma presencial y remota), hasta el proceso de reserva y gestión de pagos. De esta manera, Mobysuite mejora la experiencia de compra y venta de inmuebles al ayudar a todos los jugadores involucrados en el proceso, dándoles la posibilidad a: Compradores a efectuar el pago de sus cuotas a distancia. Inmobiliarias a automatizar su flujo comercial y mantenerlo actualizado en tiempo real. Clientes (dueños de propiedades), a separar inmuebles, pagar la separación (con Visa y Mastercad) y descargar contratos de manera fácil y automatizada. Entre otras cosas. Jugando nuestro rol en el desarrollo de Latam Nuestro compromiso a impulsar el desarrollo de la economía de Latam es lo que nos une. Pues, ambos buscamos generar la tan necesaria transformación en el mercado financiero e inmobiliario, trabajando con pasión y desarrollando las últimas tecnologías que se adapten a las necesidades de clientes y usuarios. Juntos ofrecemos una solución para que las inmobiliarias puedan gestionar sus procesos de forma segura, eficiente e intuitiva. Permitiendo, por su parte, el acceso y pago de los servicios de bienes y raíces a los clientes que lo necesiten, manteniendo así, la economía de estos países en movimiento.
Avatar img
Stella Vargas
Líder de contenido @Kushki
agosto 25, 2020

Crea tu primera API GraphQL con AWS AppSync

Tenemos mucho que compartir sobre este tema. Así que si quieres aprender al respecto mantente atento. Primero debes saber que divideremos la información en dos partes: En este artículo abordaremos los conceptos básicos de GraphQL, además diseñaremos una API sencilla desde cero y la desplegaremos con el servicio AWS AppSync y serverless framework. En la siguiente parte crearemos una aplicación del lado del cliente para consumir la API. Utilizaremos el framework Amplify+ReactJS y además daremos más funcionalidades a nuestra API mediante el uso de suscripciones para un caso de uso en tiempo real. ¿Qué es GraphQL? Graphql es un lenguaje de consulta de datos para API, la idea fundamental es hacer que la API esté disponible a través de un único endpoint, en lugar de acceder a varios como se hace actualmente con REST. Entre las ventajas de GraphQL podemos nombrar las siguientes: El cliente puede especificar exactamente la estructura de los datos que serán servidos. Carga de datos eficiente, mejorando en gran medida el uso del ancho de banda. Estilo declarativo y auto-documentativo gracias a los esquemas fuertemente tipados. Esquemas Los esquemas determinan la capacidad de la API y definen tres operaciones fundamentales: query, mutation, subscription. También incluye los parámetros de entrada y las posibles respuestas. Solucionadores Los solucionadores implementan la API y describen el comportamiento del servidor. Básicamente son funciones que se encargan de obtener datos para cada campo definido en el esquema. AWS Appsync+Serverless Framework AppSync es un servicio serverless gestionado por AWS, es una capa de GraphQL que nos permitirá desarrollar nuestra API de manera ágil. Es importante conocer los componentes básicos de AppSync: Esquema: como lo mencionamos anteriormente aquí definiremos los tipos y operaciones básicas para recuperar y guardar los datos. Solucionadores: define las plantillas de mapeo de solicitud y respuesta para cada campo definido en el esquema. Están escritas en VTL y se encargan de interpretar las respuestas de las fuentes de datos y también analizan las solicitudes. Fuentes de datos: integración con los servicios de AWS: DynamoDB, Lambda, RDS y ElasticSearch. Autenticación: podemos autenticar la API con API_KEY, IAM o Cognito User Pools Como podemos ver AppSync proporciona algunas herramientas para construir una API GraphQL de manera fluida, se puede seguir una serie de pasos desde la consola de AWS AppSync y en cuestión de minutos podemos tener algo funcional. Sin embargo preferimos hacerlo de una forma más cercana a la realidad de aplicaciones modernas en producción. Aquí entra en juego serverless framework una tecnología robusta para definir la infraestructura como código orientado a aplicaciones serverless para diferentes proveedores cloud. En Kushki creemos que hoy en día es crucial tener una infraestructura serverless versionada y automatizada, veremos que es una forma práctica y eficiente de implementar nuestra API. Serverless tiene varias opciones para desplegar AppSync en la nube. Sin más empecemos a poner en práctica todos estos conceptos mediante una sencilla aplicación. La aplicación: To do List En esta primera parte del artículo crearemos la API GraphQL de un CRUD To do List. Usaremos DynamoDB para la base de datos. Requisitos: NodeJS Cuenta en AWS (credenciales configuradas) Serverless Framework Empecemos instalando serverless y un plugin para Appsync: npm install -g serverless serverless-appsync-plugin En el directorio principal del proyecto ejecutamos el siguiente comando para crear una plantilla con las configuraciones necesarias para crear una aplicación serverless en AWS. serverless create --template aws-nodejs Nota: agrega serverless-appsync-plugin en la sección plugins del archivo serverless.yml: Primero definimos parte de nuestra infraestructura. Para esto, crearemos una tabla todos en DynamoDB en serverless.yml. Por el momento no nos preocuparemos sobre las diferentes configuraciones, con el siguiente fragmento de código bastará: resources: Resources: todos: Type: "AWS::DynamoDB::Table" Properties: TableName: todos AttributeDefinitions: - AttributeName: id AttributeType: S KeySchema: - AttributeName: id KeyType: HASH BillingMode: PAY_PER_REQUEST Define un esquema GraphQL En la raíz crea un archivo schema.graphql. Aquí es donde definimos nuestro esquema y los tipos de datos. Por el momento definiremos las operaciones query y mutation. GraphQL maneja su propia sintaxis llamada SDL, aquí puedes revisar mas sobre este tema. schema { query: Query mutation: Mutation } type Query { listToDos: [ToDo] getToDoById(id: ID!): ToDo } type Mutation { createToDo(input: CreateToDoInput!): ToDo updateToDo(input: UpdateToDoInput!): ToDo deleteToDo(id: ID!): Boolean } type ToDo { id: ID! name: String title: String! description: String completed: Boolean! } input CreateToDoInput { id: ID! name: String! title: String! description: String! completed: Boolean! } input UpdateToDoInput { name: String! title: String! description: String! completed: Boolean! } Recordemos que para cada campo definido se requiere implementar un solucionador. En este caso los solucionadores son consultas a DynamoDB escritas en VTL. Existen algunas funciones de utilidad que hacen más fácil su implementación, para más información de plantillas de mapeo de solucionadores puedes visitar este link. Solucionador createToDo: Creamos un directorio mapping-templates en la raíz del proyecto donde alojamos los solucionadores de petición y respuesta por cada campo creado en el esquema. Petición: crear archivo createToDo-request.vtl e insertar el siguiente código: { "version" : "2017-02-28", "operation" : "PutItem", "key" : { "id" : $util.dynamodb.toDynamoDBJson($context.arguments.input.id) }, "attributeValues" : { "name" : $util.dynamodb.toDynamoDBJson($context.arguments.input.name), "title" : $util.dynamodb.toDynamoDBJson($context.arguments.input.title), "description" : $util.dynamodb.toDynamoDBJson($context.arguments.input.description), "completed" : $util.dynamodb.toDynamoDBJson($context.arguments.input.completed) } } Con la variable $context.argument podemos acceder a los parámetros de entrada que hemos definido en nuestro esquema. Respuesta: crear archivo createToDo-response.vtl e insertar el siguiente código: $utils.toJson($context.result) No te preocupes en como se obtienen los datos desde DynamoDB, AppSync realiza la conexión con las fuentes de datos, los devuelve en la variable $context.result y $utils.toJson lo presenta en un formato entendible para GraphQL. Si deseas procesar estos datos en el solucionador lo puedes hacer con VTL. Solucionador updateToDo: Petición: crear archivo updateToDo-request.vtl e insertar el siguiente código, en este caso usaremos una operación de UpdateItem de DynamoDB: { "version" : "2017-02-28", "operation" : "UpdateItem", "key" : { "id" : $util.dynamodb.toDynamoDBJson($context.arguments.input.id) }, "update" : { "expression" : "SET name = :name, title = :title, description = :description, completed = :completed", "expressionValues": { ":author" : $util.dynamodb.toDynamoDBJson($context.arguments.input.name), ":title" : $util.dynamodb.toDynamoDBJson($context.arguments.input.title), ":content" : $util.dynamodb.toDynamoDBJson($context.arguments.input.description), ":url" : $util.dynamodb.toDynamoDBJson($context.arguments.input.completed) } } } Respuesta: crear archivo createToDo-response.vtl e insertar el siguiente código: $utils.toJson($context.result) Solucionador getToDoById: Petición: crear archivo getToDoById-request.vtl e insertar el siguiente código: { "version" : "2017-02-28", "operation" : "GetItem", "key" : { "id" : $util.dynamodb.toDynamoDBJson($context.args.id) } } Respuesta: crear archivo getToDoById-response.vtl e insertar el siguiente código: $utils.toJson($context.result) Definimos nuestra infraestructura de AppSync y el archivo servereless.yml en donde definimos los solucionadores (mappingTemplates), esquema (schema), fuente de datos(dataSources) y el tipo de autenticación(authenticationType), debería tener la siguiente estructura, : service: name: appsync-todo-app-backend plugins: - serverless-appsync-plugin custom: appSync: name: todo-app authenticationType: API_KEY mappingTemplates: - dataSource: todos type: Mutation field: createToDo request: "createToDo-request.vtl" response: "createToDo-response.vtl" - dataSource: todos type: Mutation field: updateToDo request: "updateToDo-request.vtl" response: "updateToDo-response.vtl" - dataSource: todos type: Query field: getToDoById request: "getToDoById-request.vtl" response: "getToDoById-response.vtl" schema: # defaults schema.graphql dataSources: - type: AMAZON_DYNAMODB name: todos description: 'Todos table' config: tableName: todos provider: name: aws runtime: nodejs12.x resources: Resources: todos: Type: "AWS::DynamoDB::Table" Properties: TableName: todos AttributeDefinitions: - AttributeName: id AttributeType: S KeySchema: - AttributeName: id KeyType: HASH BillingMode: PAY_PER_REQUEST Finalmente ejecutamos el siguiente comando para desplegar nuestra API en la nube de AWS: serverless deploy Probando nuestra API GrapQL: Si abrimos la consola de AWS AppSync veremos el esquema, los solucionadores, la autenticación y la fuente de datos que hemos definido. Por otro lado también tenemos un cliente GraphQL con el cual podemos realizar pruebas de nuestra API. En la siguiente figura podemos observar la documentación de la API de acuerdo a los esquemas definidos. Al ejecutar la operación de mutación createToDo se crea un registro en DynamoDB y devuelve el objeto creado según los campos definidos. Para recuperar los datos de un ToDo ejecutamos la operación query de getToDoById, podemos solicitar solo el campo name o los que sean necesarios. Ahí lo tuviste: En este artículo abordamos los conceptos básicos de GraphQL, además diseñamos una API sencilla desde cero y la desplegamos con el servicio AWS AppSync y serverless framework. Recuerda que aún queda una siguiente parte, en la que crearemos una aplicación del lado del cliente para consumir la API. Utilizaremos el framework Amplify+ReactJS y además daremos más funcionalidades a nuestra API mediante el uso de suscripciones para un caso de uso en tiempo real. Te esperamos en la segunda parte de este artículo.
Avatar img
Alex Suquillo
Software Developer
agosto 17, 2020