1 puntos por GN⁺ 2025-02-09 | 1 comentarios | Compartir por WhatsApp
  • 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
    • CreateSSHKeypairStep muestra el comando ssh-keygen y espera hasta que la persona usuaria presione Enter
    • GitCommitStep indica copiar la clave pública al repositorio Git y luego ejecutar git commit y git push
    • WaitForBuildStep indica esperar a que termine el trabajo en la URL del build
    • RetrieveUserEmailStep pide buscar la dirección de correo en el directorio y la guarda en context["email"]
    • SendPrivateKeyStep indica 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

 
GN⁺ 2025-02-09
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.

    • En mi no tan humilde opinión, codificar gradualmente un proceso en scripts de esta manera crea sistemas centrados en el proceso, no sistemas que devoran el proceso.
      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.
    • El enfoque anterior era así: 1) capturar el proceso actual tal cual 2) hacer que ese proceso pase la prueba de la risa 3) hacerlo automatizable.
      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.
    • Exacto. Para mí también es otra oportunidad de usar y compartir Jupyter notebooks.
      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.
    • Empiezo a ver la montaña de “Zen and the Art of Motorcycle Maintenance”.
      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í.
    • Me gustaría que el script hiciera directamente las cosas que ya se pueden hacer con comandos.
      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: o Put 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

    • Hacer que usuarios no expertos administren sus propias claves tampoco parece muy seguro. Por eso la idea central es pasarlo a un script.
    • El paso de que el usuario debe generar personalmente la clave privada y entregar solo la clave pública al administrador del sistema siempre 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.
    • ¿De verdad ese es el estándar mínimo? Al fin y al cabo, ¿IT no es dueño de todas las partes de la máquina de trabajo que contiene la clave privada? Entiendo que con las contraseñas es distinto, pero la clave privada queda almacenada en la máquina.
  • 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.

    • Exacto.
      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): ...

    • Pero ¿cómo sobreviviríamos sin ingerir una abstracción completamente rota una vez al día?
    • La ventaja del enfoque original es que, si más adelante hace falta, puedes simplemente agregar métodos privados que pertenezcan solo a esa clase.
      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.
    • Me recuerda a https://www.youtube.com/watch?v=QM1iUe6IofM de Brain Will. Tiene una serie que básicamente se queja de temas como este.
      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.

    • Con una mejor librería de línea de comandos podrías mostrar la checklist y la salida de ejecución de cada paso. Es un enfoque razonable sin importar qué pasos estén automatizados.
      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.
    • Me alegra que haya salido el punto de que “no se puede interrumpir”. Por eso uso Makefile en vez de scripts Bash.
      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 con make.
      Pero escribir ese Makefile es realmente doloroso. ¿Habrá una solución mejor?
    • Cuando hago cosas de este tipo, dejo estado persistente para que se puedan interrumpir. Por ejemplo, si es una tarea anual, la ejecuto como ./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 touch del archivo 2025/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.
    • ¿Esto es realmente una crítica al artículo? Además tiraste la conclusión y te fuiste. ¿Qué solución es “la solución más simple”?
    • He usado scripts parecidos, y si por accidente pones una dirección de email incorrecta, te quedas en “¿y ahora qué hago?”. ¿Hay que reiniciar todo el script? Quedar atrapado en el script puede ser doloroso.
  • 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”.

    • Me gustaría que compartieras uno o más ejemplos con más detalle, o que resumieras tu experiencia y consejos. Lo leería aquí o en un post de blog.
      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 implemented de 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.

    • Por lo general, alguna parte se puede automatizar, o algunos pasos manuales se pueden verificar. Entonces, de repente, se convierte en un script que hace algo.