- En los equipos de operaciones siempre quedan procedimientos manuales (toil) difíciles de eliminar por completo, como cambios de infraestructura o aprovisionamiento de cuentas, y mientras más crece la empresa, más pasos y excepciones aparecen
- Aunque cada paso parezca automatizable, si solo se convierten algunos en scripts, proliferan las herramientas de propósito único y la persona usuaria sigue teniendo que seguir documentos de procedimiento largos
- Un script de no hacer nada no ejecuta automáticamente el trabajo real; en cambio, envuelve cada paso del procedimiento en una función y guía a la persona usuaria paso por paso
- Así, la persona usuaria tiene menos probabilidades de perderse o saltarse pasos, y para quien desarrolla luego resulta más fácil cambiar el texto de guía de un paso específico por código de automatización real
- No reduce de inmediato la cantidad de trabajo manual, pero baja el costo inicial de empezar a automatizar, lo que permite eliminar gradualmente el toil con el tiempo
Cuando un procedimiento manual se vuelve una carga
- En todo equipo de operaciones todavía existen procedimientos manuales que no se han automatizado, y es difícil que el toil desaparezca por completo
- En una empresa en crecimiento, procedimientos como cambios de infraestructura o aprovisionamiento de cuentas de usuario suelen convertirse en una fuente importante de toil
- Un proceso de aprovisionamiento de cuentas de usuario puede incluir pasos como estos
- Generar el par de claves SSH de la persona usuaria
- Hacer commit de la clave pública en Git y hacer push a
master - Esperar a que termine el trabajo de build
- Verificar la dirección de correo de la persona usuaria en el directorio de empleados
- Entregar la clave privada a la persona usuaria mediante 1Password
- En entornos reales, el procedimiento puede crecer hasta 20 pasos, o exigir seguir constantemente bifurcaciones y casos especiales durante la ejecución
- Este tipo de trabajo exige mucha concentración, pero se parece más a marcar una casilla más que a resolver un problema interesante, por lo que termina siendo un trabajo tedioso
Los huecos que deja la automatización parcial
- El trabajo tedioso parece un buen candidato para automatizar
- Es fácil imaginar cómo automatizar cada paso
- Las computadoras pueden seguir instrucciones más rápido y con mayor precisión que las personas
- También es menos probable que aparezca deriva práctica (practical drift)
- El problema es que automatizar este tipo de trabajo a menudo se siente como algo de todo o nada
- Se pueden crear scripts que resuelvan solo 2 o 5 pasos, pero eso no reduce mucho la molestia del procedimiento completo
- Cuando aumentan los scripts de propósito único, cada herramienta termina teniendo convenciones y comportamientos esperados distintos, y la persona usuaria aún debe seguir documentación de varios pasos
Cómo funciona un script de no hacer nada
- Casi cualquier trabajo tedioso puede convertirse en un script de no hacer nada
- La idea central es llevar las instrucciones del trabajo al código y encapsular cada paso en una función
- El flujo del script de ejemplo es el siguiente
CreateSSHKeypairStepmuestra el comandossh-keygeny espera hasta que la persona usuaria presione EnterGitCommitStepindica copiar la clave pública al repositorio Git y luego ejecutargit commitygit pushWaitForBuildStepindica esperar a que termine el trabajo en la URL del buildRetrieveUserEmailSteppide buscar la dirección de correo en el directorio y la guarda encontext["email"]SendPrivateKeyStepindica crear un documento de clave privada en 1Password y compartirlo con la persona usuaria de ese correo
- Este script no realiza realmente ninguno de los pasos del procedimiento; simplemente guía a la persona usuaria uno por uno y espera la finalización manual
El camino hacia la automatización
- A primera vista, un script de no hacer nada puede parecer una forma de hacer más difícil la lectura de la documentación, pero en la práctica ayuda a mantener el flujo de trabajo de forma más segura
- Reduce la probabilidad de que la persona usuaria pierda el punto en el que va o se salte pasos
- Facilita mantener la concentración y completar el trabajo tedioso hasta el final
- Como cada paso está separado en funciones, se puede reemplazar el texto de un paso específico por código que ejecute la acción real
- Con el tiempo, se forma una biblioteca de pasos reutilizables y la automatización posterior se vuelve más eficiente
- El script de no hacer nada en sí no reduce la cantidad de trabajo manual del equipo
- Su valor está en dejar lista una base desde la cual sea fácil empezar a automatizar, para que el equipo pueda eliminar el toil de manera gradual con el tiempo
1 comentarios
Opiniones en Hacker News
Me gusta mucho este enfoque.
En términos generales, es otra forma de definir una interfaz alrededor de un proceso. Ese proceso puede ser manual o estar automatizado, pero la interfaz puede mantenerse igual. Por eso es bastante potente cuando automatizas pasos.
Basta con aplicarlo igual que lo harías con cualquier otro sistema.
En el pasado llené manualmente Google Sheets y luego lo automaticé con un script; también hice que, al crear un ticket de Jira, este se tomara automáticamente y se procesara. Puedes empezar más rápido, automatizar solo las partes más molestas y no necesariamente tienes que automatizarlo todo.
Un efecto secundario de los scripts que no hacen nada es que, como es más probable que se usen que la documentación, pueden mantenerse actualizados con más frecuencia.
Estoy a favor de tener una lista de scripts que automaticen tareas comunes. Pero en cuanto esos scripts empiezan a ser invocados por servicios en producción, se genera una enorme deuda técnica para la desafortunada persona que tenga que desenredar esa red de espagueti.
Más aún, como el proceso centrado en personas terminó codificando el sistema, se vuelve imposible hacer cambios favorables para el sistema de software, por ejemplo dividirlo en componentes. Al final, la expansión gradual consiste en meter más cosas dentro del proceso, y eso se convierte en un ciclo de autoperpetuación que sigue agregando piezas al monolito de scripts.
Mientras avanzas con 3 y 4, haz que la mayor cantidad posible de personas use el proceso de forma iterativa y ajústalo según los usos indebidos que aparezcan en el mundo real.
4) Automatizar el proceso.
Todo el mundo está de acuerdo con 1 y 2, y la mayoría termina aceptando 4, pero al hacer 3 aumenta la cantidad de personas que piden y entienden mejor 4.
El límite de este enfoque, sin embargo, es que funciona si puedes automatizar el inicio o el final del proceso, pero si en medio hay dos puntos de automatización aislados como islas, no es mejor que una herramienta de línea de comandos con prompts.
Puedes explicar qué hay que hacer y proporcionar boilerplate, ejemplos o ejecutables parametrizados.
Sería genial usar notebooks prácticamente como sistema de documentación. Aunque son demasiado pesados para ponerlos como una capa encima de un SaaS en la nube como Confluence, y en su forma actual también dejan demasiado margen para problemas como la escalada de privilegios.
Este enfoque convierte una página guía de Confluence en un walkthrough medio interactivo. Ese es el lado consciente.
El otro lado es la automatización de pruebas. Al principio empieza como un montón de XPath sobreajustado y pasos no documentados. Cada vez que cambia la aplicación, terminas redescubriendo esos pasos. Ese es el lado inconsciente.
Ojalá podamos llegar a la cima y ejecutarlo rápido, sin dejar de saber cómo llegamos hasta ahí y por qué quedó así.
Basta con pedir confirmación al usuario, como
Execute command (y/N)?.Odio tener que copiar y pegar de una terminal a otra. Eso también consume mucha concentración.
Solo habría que preguntarle al usuario por las tareas manuales que todavía no son comandos:
Look up the e-mail address for foo. Paste it here:oPut that shit in 1Password: Are you done (y/N)?Es un enfoque interesante.
Pero la tarea usada como ejemplo solo muestra lo insegura que era la forma en que esa empresa entregaba claves SSH. En realidad, debería inculcarse que el usuario genere personalmente su clave privada y entregue solo la clave pública al administrador del sistema para que le otorgue acceso. En ningún momento el administrador del sistema debería tener una copia de la clave privada, ni siquiera temporalmente. Por lo tanto, el paso de 1Password ni siquiera debería ser necesario.
Como referencia, soy el autor de github-keygen, una herramienta que automatiza la generación de claves SSH dedicadas al acceso a GitHub y la configuración SSH para ese contexto.
https://github.com/dolmen/github-keygen
el usuario debe generar personalmente la clave privada y entregar solo la clave pública al administrador del sistemasiempre fue molesto de implementar.Nosotros pasamos de SSH a autenticación basada en certificados, y ya no movemos claves públicas de un lado a otro. Todo el proceso se simplificó muchísimo.
Terminé probando este enfoque recién como un año después de que se publicara este artículo por primera vez.
Por un bug en nuestra cadena de herramientas, el runbook para hotfixes era más o menos el doble de complicado que el proceso de release normal.
No recibió el reconocimiento que merecía, pero algo que antes se usaba quizá una vez cada 10 semanas, solo para incidentes sev 1 o épicas en etapa final, pasó a usarse en promedio una vez por semana, y algunas semanas hasta 3 veces. Como ya no hacía falta convertir todo en feature toggles, pudimos meternos mucho más a fondo con la deuda técnica.
Si eres una empresa chica y te resulta fácil replicar datos de producción en un entorno de preproducción, tal vez no veas estos resultados. Pero nosotros teníamos más de 150 endpoints con los que nos comunicábamos, creo que en promedio unos 3 por servicio. Había muchísimos datasets, y algunos se recolectaban con algo parecido a Kafka antes de que existiera Kafka.
Solo una persona intentaba replicar datos de producción, y tampoco tenía tiempo ni energía suficientes, así que apenas podía hacerlo una o dos veces al año. Ese ritmo era mucho más lento que la velocidad a la que cambiaban los clientes y las funcionalidades. Al final teníamos que trastear con el proceso de despliegue blue-green y jmeter para descubrir si estábamos cerca, y cómo medir éxito/fracaso antes de salir en vivo.
Al final, lo que frenaba a la gente era un proceso de build minucioso y propenso a errores, y eso recién se destrabó cuando lo automaticé a medias.
Más tarde, a medida que aumentó el uso, busqué todas las URL de los pasos manuales y las puse en una tabla de consulta dentro de la herramienta, y también las expuse en el proceso normal de verificación para aprobar releases. Gracias a eso, el coordinador trabajaba un poco más rápido y con menos estrés. Ese proceso era tan molesto que tres equipos se turnaban para repartir la carga.
Cuando se dice “bajar la energía de activación de la automatización de tareas”, ¿significa básicamente que un script que no hace nada luego termina teniendo pasos que sí automatizan algo de verdad?
Si se lo ve como un placeholder para automatización futura, se siente como un buen equilibrio entre automatización y eficiencia. Puedes hacer un primer intento sin invertir demasiado, y dejar fruta al alcance de la mano para cuando más adelante el esfuerzo tenga un valor más claro.
Como cada paso del procedimiento ahora está encapsulado en una función, puedes reemplazar el texto de un paso específico por código que realice automáticamente la acción real.
class Foo(object): def run(self, context): ...Un objeto con un solo método de ejecución ya viene incorporado en Python. Se llama función.
def foo(context): ...Con el enfoque de funciones, si necesitas una función nueva, la agregas a nivel global. Si son una o dos, está perfectamente bien, pero si empiezan a ser más, terminas con un montón de funciones al mismo nivel y las dependencias entre ellas dejan de ser claras.
En uno de esos videos muestra ejemplos de cómo simplificar código innecesariamente abstraído.
Excelente, pero no se puede interrumpir.
Sería bueno mostrar todos los pasos de antemano e ir marcando cada ítem a medida que avanzas. A veces conviene prepararse de verdad con una visión más amplia.
También se podría dejar un log del resumen en un archivo.
Hay tantas cosas que se podrían mejorar que quizá, justamente, la solución más simple sea la mejor.
Pero un script de shell que no hace nada es tan fácil de empezar que cuesta no terminarlo. Tal vez convenga usar ese esfuerzo en automatizar un paso. Puedes caer en pantanos entretenidos pero no muy productivos, como decidir qué librería TUI usar o cómo estructurarlo.
Cada paso es una regla con nombre
*.done, y cuando se completa crea un archivo.done. Puedes interrumpir en cualquier momento, modificar el script para arreglar algo y luego reanudar conmake.Pero escribir ese Makefile es realmente doloroso. ¿Habrá una solución mejor?
./do-the-thing.sh 2025, creo un directorio 2025 y ahí guardo el estado de hasta dónde llegó.Si apruebas el primer paso, puedes hacer
touchdel archivo2025/first-step. Si el script muere o se interrumpe y luego lo vuelves a ejecutar, revisa ese archivo y se salta el primer paso.Cuando algo cambia y la automatización deja de funcionar, es útil poder salir sin perder el estado, arreglar el script y volver a ejecutarlo.
Normalmente hago que el script solo indique el siguiente paso manual y luego termine. Así puedes usar la terminal para otras cosas. Con el historial de comandos es fácil volver a ejecutar el script.
También hay discusiones anteriores. Con muchos comentarios.
https://news.ycombinator.com/item?id=29083367 - hace 3 años, 230 comentarios
https://news.ycombinator.com/item?id=20495739 - hace 6 años, 124 comentarios
No puedo exagerar cuánto me gusta este enfoque.
Lo he aplicado con éxito en varios proyectos. Mi ejemplo favorito es un robot quirúrgico de 30 millones de dólares que fallaba en las pruebas de laboratorio por “factores humanos”.
Yo estoy en otro campo, la práctica legal, pero me gustaría pensar cómo aplicar este enfoque en nuestra firma.
Me gusta este enfoque. Incluso en sistemas basados en lenguajes de programación con cierto nivel de complejidad, ya me gusta hacer algo parecido. En programación funcional parece que a esto le llaman huecos (holes).
El error
not implementedde una interfaz sigue una lógica similar, pero creo que hay bastante valor en escribir algo trivial que produzca una salida válida, aunque sin significado, para cada una de varias piezas que dependen entre sí. Eso acelera el proceso de crear esas piezas y hace mucho más probable que se prueben y construyan una por una. Reduce la necesidad de escribir varias partes de golpe antes de empezar a probar.En el contexto de scripts, como en los casos de uso tratados en el artículo, a veces puede ser difícil que esa validez a nivel de tipos sea importante. Al fin y al cabo, muchos de los efectos de la línea de comandos serían efectos secundarios desde una perspectiva funcional. Pero como se avanza de manera secuencial, el impacto es mucho menor, y gracias a los prompts de espera se puede preservar el orden de las tareas manteniendo, con poco costo, los pasos manuales que de todos modos habría que hacer aun sin el script.
El andamiaje es incompleto, pero fundamentalmente útil.
En teoría suena bien, pero en la práctica parece difícil.
Si el equipo de operaciones repite la misma tarea y ve que un script que no hace nada realmente no hace nada, en cuanto piense que ya memorizó los pasos, o que hacerlo manualmente es más rápido o más interesante, dejará de usarlo rápidamente.
He escrito mucha automatización y documentación para equipos de operaciones, pero lograr que la gente las use y las siga usando siempre fue un problema. Incluso los cambios en la documentación requerían avisos. Cuando la gente aprende a hacer algo, rápidamente deja de leer la documentación.
En un mundo perfecto, este enfoque tiene mucho sentido, y creo que podría usarlo para mis propias tareas. Pero la realidad casi nunca es perfecta. Yo solo usaría este método cuando el 90% ya esté automatizado y quede un único paso que todavía no se pudo resolver. Incluso entonces, parte del equipo de operaciones podría saltarse ese paso manual y asumir que todo es magia completamente automatizada.