El camino freelance, parte 4: contratos

Muchas veces cuando trabajamos como ingenieros/programadores en un esquema de relación de dependencia no le prestamos mayor atención a las cuestiones contractuales. «Alguien» consigue los proyectos ya sea canalizando pedidos/necesidades de otras áreas (si desarrollamos software in-house) o bien vendiendo a algún cliente (si somos una software factory). Pero si vas a trabajar por tu cuenta deberías al menos tener algunos puntos presentes para encarar tus proyectos.

En términos generales y de forma muy simplificada existen dos tipos de contratos: los llave en mano y los Time&Materials.

En un contrato llave en mano, se define el proyecto completo antes de comenzar fijando el alcance del software a entregar y uno cobra un monto fijo también establecido al comienzo del proyecto por entregar la pieza de software en cuestión. Esta forma de contratación es muy común en construcciones civiles pero llevada al software muchas veces suele traer algunos inconvenientes por el simple hecho que suele resultar complejo determinar el alcance en forma temprana e incluso cuando se logra hacerlo siempre aparecen cambios y de la mano de ellos la necesidad de revisar el contrato.

En un contrato Time&Materials no hay un alcance fijo, sino que el alcance se ajustar sobre la marcha pero lo que se fija es un precio/hora. De esta forma el manejo de cambios es mucho más simple. El tema con esta forma de contratación es que uno como proveedor debe trabajar mucho más enfocado pues el cliente está pagando por cada momento que invertimos en el proyecto y por ello en cierto modo tenemos una responsabilidad mayor en asegurar que nuestras actividades agregan valor. No es que trabajando llave en mano uno no tenga responsabilidad, pero justamente al ser llave en mano, todo riesgo de retrasos lo estamos asumiendo nosotros (típicamente) sin impactar en los costos del cliente.

Estas dos modalidades representan dos extremos en los distintos esquemas de contratación dando lugar en el medio a infinitos posibles esquemas más cerca de uno u otro extremo.

Personalmente (freelance o no) me inclino a trabajar en un esquema Time&Materials. Más aún, desde que trabajo en forma independiente todos mis trabajos hasta el momento han sido con un esquema Time&Materials. Ahora bien, para que un proyecto en esta modalidad llegue a buen puerto creo que hay un par de puntos fundamentales que trataré en el próximo post.

Continuará…

Tablero Integrado de Equipo

Me uní a mi equipo cuando este ya llevaba varios meses trabajando en el proyecto. Una práctica que me sorprendió es que todo el código de la aplicación pasa por una revisión de pares utilizando merge-requests. Personalmente prefiero el pair-programming a las revisiones de código pero ese es tema de otro post. El punto aquí es que esta forma de trabajo nos lleva a que frecuentemente se nos acumulen merge-request esperando a ser revisados y retrasando el flujo de entrega. Al mismo tiempo ocurre que el autor del merge-request no puede dar por cerrada la story y para no estar ocioso comienza a trabajar en una nueva story aumentando así el work in progress (wip). Punto aparte.

El fin de semana estaba leyendo el capítulo de Visual Management de @SolePinter y de repente se me ocurrió que si tuviéramos esta información bien presente al alcance de la mano eso podría ser un buen primer paso para la solución del problema. Como el equipo está distribuido, el tablero físico no iba a funcionar así que aprovechando que hacía rato que no programaba Ruby me senté y me dí el gusto de programar un tablero digital que muestra en una misma pantalla la cantidad de merge-request activos en todos nuestros repositorios, la cantidad de tareas en curso en nuestro backlog (consultando Trello) y algunas otras cosillas. Además de consultar la información tiene cierta lógica para actuar de semáforo, pintando de rojo o verde cada indicar dependiendo de cierto límites pre-configurados.

tid_v1

Si vemos que esto funciona es posible que siga agregando funcionalidades al tablero y en una de esas tal vez lo comparta para que lo usen otros equipos.

El camino freelancer, parte 3: la mejor parte

Cuando empecé a recorrer este camino lo que más valoraba era la libertad horaria. Con el correr del tiempo comencé a valorar otros aspectos, todos ellos relacionados con la posibilidad de elegir: elegir mis proyectos, elegir mis clientes, elegir mis compañeros de trabajo, elegir la fecha y extensión de mis vacaciones.

Obviamente a la hora de elegir uno debe poner diversos factores en la balanza: expectativas económicas, motivación, finanzas, valor estratégico, diversión, seguridad, probabilidad de éxito, etc, etc. Lo bueno es que es uno mismo quien realiza la ponderación de cada uno de esos factores.

En este sentido si estas pensando en comenzar tu camino freelancer podrías ir pensando cuales sería tus criterios para elegir tus proyectos.

Continuará…

El camino freelancer, parte 2: las cosas no tan lindas

El trabajar de forma independiente trae de la mano ciertos beneficios pero también algunas cuestiones no tan «lindas», algunas de ellas conocidas y otras no tanto, sobre todo cuando uno viene de trabajar en relación de dependencia.

Debes encargarte de conseguir tus propios trabajos, ya no hay una organización que lo haga por ti. Este punto es posiblemente la mayor barrera para muchos que tienen la intención de iniciar el camino independiente. Personalmente creo que se percibe esta cuestión como mucho más difícil de lo que realmente es.

Debes encargarte de las cobranzas y finanzas. Cuando trabajas en relación de dependencia en general tu sueldo llega a comienzo de cada mes sin que tengas que enviar recordatorios ni andar persiguiendo a nadie. Cuando trabajas como independiente, dependiendo de quienes sean tus clientes puede que:

  • La persona que te contrata no es necesariamente la que te paga. Si tu cliente es una empresa puede que quien te contrate sea alguien del área de sistemas pero indefectiblemente quien te pagará será un área de proveedores o compras, gente que seguramente no te conozca y para quien serás posiblemente un proveedor más.
  • Los pagos los recibas en diferido, hay empresas que tienen políticas de pago a 30 días, o sea que: trabajas durante todo marzo, facturas a fin de marzo/comienzo de abril, pero cobras recién en mayo.

Debes encargarte de las cuestiones impositivas/legales, generalmente al trabajar en relación de dependencia tu empleador se encarga de la mayoría de estas cuestiones (al menos en Argentina), pero al ser freelancer estas por tu cuenta. Deberás contactar un contador para que te ayude con estas cuestiones o al menos para que te asesore inicialmente y luego llevar el tema tu mismo.

Debes planificar tus vacaciones siendo consciente de que puedes tomarte todas las vacaciones que gustes pero sabiendo también que durante ese período no generarás ingresos.

Se que todas estas cosas pueden sonar un poco abrumadoras, pero no lo son tanto y para que no pinte el bajón, en el próximo post prometo buenas noticias.

Continuará…

El camino freelancer, parte 1: motivación

Recurrente recibo consultas, tanto de alumnos como de colegas, sobre cómo hacer para comenzar a trabajar de forma independiente (freelance) y es por ello que finalmente he decido poner por escrito lo que he contestado ya muchísimas veces. Como un único post podría llegar a resultar muy extenso, he decidido escribir un conjunto de posts, cada uno de ellos enfocado en una cuestión particular. Este primer post lo voy a dedicar las motivaciones para trabajar independiente.

Cada vez que recibo una consulta de este tipo lo primero que hago es consultar al interesado cuales son sus motivaciones para querer trabajar de forma independiente. Esto es central pues dependiendo de la motivaciones de cada uno puede que el trabajo independiente no sea lo más apropiado.

Muchos me dicen que quieren trabajar como independientes para tener así mayor flexibilidad horaria. Bien, es cierto, en teoría el trabajar de forma independiente permite tener mayor flexibilidad horaria, pero ojo porque mayor flexibilidad no significa trabajar menos. Conozco muchos trabajadores independientes que trabajan muchas más horas que el promedio de los trabajadores en relación de dependencia que hacen el mismo tipo de tareas.  Al mismo tiempo, creo que hoy en día los esquemas de trabajo se han flexibilizado muchísimo (al menos en el mundo de la informática)  con lo cual es perfectamente factible trabajar en relación de dependencia con un acuerdo de homeworking casi completo y/o con un límite inferior a 40 horas semanales. Dada esta realidad, si lo buscas es flexibilidad horaria una opción a considerar antes del trabajo independiente, es trabajar en relación de dependencia en una empresa con «políticas flexibles».

Otro argumento común que suelo escuchar es «libertad»: «quiero tener la libertad de trabajar desde la playa o cualquier otro lugar». Este argumento es en un punto análogo al anterior, no hace falta trabajar de forma independiente para tener este tipo de libertad, existen hoy en día muchas empresas dispuestas que sus empleados trabajen en forma remota desde cualquier lugar. En general esperan que uno esté disponible en determinada banda horaria, lo cual es completamente razonable y al mismo tiempo es algo que también suele ocurrir a los freelancers.

Algunos me dicen que les gustaría trabajar utilizando determinadas tecnologías. Aquí la cuestión del trabajo independiente puede tener más sentido. En general las empresas trabajan con un conjunto determinado de tecnologías y no es común que vayan cambiando muy frecuentemente ante las modas del mercado. Incluso en aquellas empresas donde se trabaja con múltiples tecnologías, no suele ser tan simple moverse entre proyectos de distintas tecnologías si uno no tiene el mismo nivel de experiencia/seniority en todas ellas. Aún así creo que hay que distinguir dos escenarios: una cosa es querer trabajar con una determinada tecnología y otra distinta es querer poder cambiar de tecnología «frecuentemente». Lo primero bien puede resolver con una cambio de empresa, mientras que los segundo es más complejo, incluso trabajando de forma independiente.

Algunos otros argumentos comunes que suelo escuchar son:

  • Poder elegir en qué proyectos participar
  • Poder elegir cuando y cuanto vacacionar
  • Construir algo propio

Creo que todas son razones válidas y el trabajo independiente puede satisfacerlas, pero antes de mandarse hay que tener en cuenta algunos puntos «no tan felices» del trabajo independiente, pero ello será parte del siguiente post.

Continuará…

Estrategias de provisioning + deployment (parte 2)

En el proyecto en el que estoy trabajando actualmente utilizamos Ansible para hacer el provisioning de la infraestructura y CodeDeploy para manejar el deployment. CodeDeploy es un servicio que Amazon provee gratuitamente a los usuarios de EC2, la plataforma cloud de servidores virtualizados de Amazon.

El funcionamiento de CodeDeploy es bastante simple: copia archivos desde Github o S3 hacia el servidor destino y permite como parte de ese proceso ejecutar algunos scripts. Pero más allá de este funcionamiento simple, la parte más valiosa de CodeDeploy es la capacidad de trabajar en conjunto con el mecanismo de auto-scaling de Amazon de forma de simplificar el deployment a una cantidad variable de instancias ofreciendo incluso algunas variantes de estrategia (one-by-one, all-together, half-and-half).

La siguiente imagen ofrece una vista de alto nivel del proceso de deployment que estamos usando en el proyecto.

ansible_codedeploy

Continuará…

Hacia un esquema de entrega continua

Cuando me uní al proyecto el equipo venia trabajando con un esquema ágil «clásico» pero con algunas particularidades:

  • Iteraciones time-boxed de 2 semanas
  • Congelamiento y regresión/estabilización los últimos dias de la iteración
  • Pruebas unitarias automatizadas
  • Regresión manual
  • Release al final de la iteración

Esta forma de trabajo ocasionaba de vez en cuando que se llegara al final de iteración con funcionalidades «inestables» porque no se llegaba a tiempo a completar la regresión/estabilización. Personalmente ya me había cruzado con este tipo de situaciones en el pasado y por ello en una retrospectiva propuse al equipo hacer un experimento en la siguiente iteración: tomar una user story, implementarla, testearla y releasearla apenas se la termine sin esperar al final de la iteración. De esta forma:

  • El flujo de entrega sería más frecuente bajando la ansidad de cliente
  • Obtendríamos feedback más temprano del usuario
  • El esfuerzo de estabilización estaría distribuido a lo largo de toda la iteración (y posiblemente sería menor en términos generales)
  • Se evitaría el incremento del WIP (work in progress) ya que las user stories completas no quedarían esperando al final de la iteración para su release.

Cuando hice esta propuesta algunos miembros del equipo me miraron con cierta desconfianza pero a pesar de eso todos estuvimos de acuerdo en hacer el experimento.

Continuará…

eXtreme Programming Moderno: ¿de qué estamos hablando?

Muchas cosas han cambiado desde la publicación del libro de Extreme Programming Explained de Ken Beck que estableció las bases de XP. Sucesivas publicaciones han ido actualizando las prácticas de XP. En ese sentido me ha resultado muy interesante el libro de James Shore y Shane Warden, The Art of Agile Development el cual más allá de su nombre es básicamente un libro de XP. Pero así y todo este libro es de 2007, casi 10 años han pasado y la forma en que trabajan los equipos de XP se ha visto modificada principalmente a partir de la incorporación de nuevas prácticas dando origen a lo que llamo Modern Extreme Programming (si, son consciente, el nombre no es bueno).

Más concretamente cuando hablo de Modern XP me refiero a la forma en que trabajan actualmente (hoy, 2016) muchos equipos que utilizan XP. Aquí me parece importante destacar que en general no he visto equipos explícitamente preocupados por aplicar XP (como si los he visto por aplicar Scrum) sino que en general la preocupación pasa por entregar valor y calidad y en ese sentido simplemente utilizan la mayoría de las prácticas de XP por el simple hecho de que les funcionan. Más aún, he visto equipos haciendo XP sin saber que lo están haciendo. En este sentido veo un conjunto de «nuevas» prácticas claramente establecidas y otro conjunto de prácticas «experimentales» menos establecidas, o no probadas o incluso descartadas por algunos equipos.

Prácticas establecidas

Visual Story Mapping (VSM) es un técnica para creación de backlog popularizada por Jeff Patton. VSM es una actividad realizada típicamente al comienzo del proyecto, en etapa de definición/pre-venta y cuyo output es un artefacto concreto: «un mapa». Este mapa permite visualizar fácilmente actores, flujos de negocio y funcionalidades/user stories. Creo que el gran valor de esta actividad radica no solo el mapa resultante sino en las discusión que se disparan durante su realización.

Specification by Example (SBE) también conocida como Behaviour-Driven Development (BDD) es un enfoque colaborativo para la definición de requerimientos usando ejemplos concretos de uso en lugar de especificaciones abstractas/genéricas. Algunas de las herramientas que han ayudado a popularizar esta técnica son Cucumber, JBehave y SpecFlow.

Infrastructure as Code (IAC) describir la infraestructura con código nos permite generar nuevos ambientes on-demand y así acelerar diversas tareas del proceso de desarrollo. Al mismo tiempo es posible aplicar ciertas prácticas comunes del desarrollo como versionado y prueba automatizada. En los últimos años han aparecido herramientas como Puppet, Chef y Ansible que han posibilitado esta práctica y han potenciado su difusión.

Continuous Delivery (CD) es la capacidad de entregar software funcionando en manos del usuario de una forma segura, rápida y sostenible. La entrega frecuente ha estado entre las prácticas fundacionales de agile desde un comienzo pero CD va más allá, llevando al extremo la frecuencia a partir de un foco importante en la automatización. Es común encontrar equipos haciendo CD y realizando varias entregas en un mismo día.

Prácticas experimentales

#NoEstimates es un enfoque de trabajo que propone no realizar estimaciones de user stories lo cual impacta directamente en el Planning game. Si bien hay una iniciativa con popularidad creciente alrededor de #NoEstimates, creo que su uso no está lo suficientemente extendido como para considerarla una práctica del nuevo XP.

Test-Driven Infrastructure surge a partir de la práctica de Infraestructura as Code y pretende llevar la práctica de TDD al mundo de la infraestructura. Personalmente he intentando utilizarla y no me convenció, creo que me trajo más inconvenientes que soluciones. Tampoco conozco en forma directa equipos que la estén utilizando, pero la menciono pues he leído y escuchado al respecto en algunos encuentros de la comunidad.

Continuous Deployment es una práctica es un paso más allá de Continuous Delivery y tiene que ver con ir a producción en forma automática. Típicamente en Continuous Deployment el paso final para ir a producción se dispara en forma manual a partir de una decisión de negocio. Cuando hablamos de continuous deployment la decisión de negocio ya está tomada: cuando algo se termina va directo a producción con lo cual se elimina el trigger manual.

Mob Programming es en cierto modo la idea de Pair-Programming llevada al extremo: todo el código, se escribe todo el tiempo en una única máquina con todo el equipo trabajando junto. El hecho de trabajar todo el equipo en una máquina en ciertos momentos del proyecto es algo que he visto en muchos equipos y yo muchas veces lo hago, sobre todo al comienzo de los proyectos. Pero hacerlo con todo el equipo todo el tiempo es algo que no he visto, aunque los impulsores de este movimiento han reportado interesantes resultados.

Estrategias de provisioning + deployment (parte 1)

En los últimos años he participado en diversos proyectos utilizando diversas estrategias de deployment. Dado que este es un tema que está despertando cada vez más interés me parece que puedo colaborar compartiendo las experiencias que he tenido.

Esta primer estrategia que quiero compartir está basada en Puppet y en paquetes Debian. Todo el provisioning del ambiente se hace utilizando Puppet y luego para el deployment se usa el siguiente proceso:

  1. Jenkins buildea la aplicación y genera un paquete Debian incluyendo la aplicación buildeada.
  2. El paquete generado se publica en un repositorio de paquetes Debian.
  3. Se actualiza el Puppet master con la definición del nuevo paquete.
  4. Se envía un mensaje a cada máquina del ambiente para que el agente Puppet actualice la máquina instalando el nuevo paquete que trae la nueva versión de la aplicación. (esto es necesario porque generalmente no se quiere una actualización automática de los agentes y por ello su actualización automática está desactivada)

Algunos puntos interesantes de esta estrategia son:

  • Es muy fácil realizar el rollback pues se hace utilizando el sistema de paquetes del sistema operativo
  • El tratar nuestra aplicación como un paquete del sistema operativo gozamos de todos los beneficios/funcionalidades que provee el sistema operativo para gestión de paquetes. Un ejemplo de esto es la posibilidad de explicar las dependencias de nuestra aplicación con otros paquetes dejando así que el propio gestor de paquetes se encargue de su resolución.
  • Si bien en mi descripción me refiero a paquetes Debian (.deb) lo mismo puede hacer con paquetes de otras distribuciones.
  • Dependiendo de cómo se armen los paquetes, se puede  incluir en los mismos los archivos de configuración  de la aplicación.

sopackages_puppet

Esta estrategia (y algunas más) la estaré compartiendo con mayor profundidad en mi Taller de prácticas de DevOps que dictaré el próximo 19 de abril.

Continuará..

Nuevo proyecto: Python, iPhone y Amazon

Hace un par de semanas me sumé a un nuevo proyecto para colaborar en cuestiones de operaciones/arquitectura. Cuando me hicieron la propuesta para sumarme no lo dudé ni un momento pues el contexto me resultó super interesante:

  • Plataforma multi-tenant de administración de contenido + aplicación móvil para consumo del contenido
  • Integración con redes sociales
  • Características de red social (contenido social compartido, picos de carga, potencial de cientos de miles de usuarios, etc)
  • Frontends Angular y iPhone
  • Backend Python
  • Infraestructura Cloud en Amazon
  • Equipo de 12 personas incluyendo devs, un especialista en ux, un tester y un coach (y ahora yo en rol de devop)
  • Cliente remoto (en US) y equipo de ingeniería distribuido en 3 cuidades.

Continuará…