Skip to content

Terraform y los peligros de aplicar localmente ​

INFO

Esta publicación fue escrita originalmente el 13 de julio de 2018

Publicación original: https://medium.com/runatlantis/terraform-and-the-dangers-of-applying-locally-543563782a73

Si estás usando Terraform, entonces en algún momento probablemente ejecutaste un terraform apply que revirtió el cambio de otra persona.

Así es como eso tiende a suceder:

La configuración ​

Supongamos que tenemos dos desarrolladores: Alice y Bob. Alice necesita agregar una nueva regla de grupo de seguridad. Ella hace checkout de una nueva rama, agrega su regla y crea un pull request:

Cuando ejecuta terraform plan localmente, ve lo que espera.

Mientras tanto, Bob está trabajando en una corrección de emergencia. Hace checkout de una nueva rama y agrega una regla de grupo de seguridad diferente llamada emergency:

Y, debido a que es una emergencia, ejecuta apply inmediatamente:

Ahora volvamos a Alice. Ella acaba de recibir aprobación sobre el cambio de su pull request y entonces ejecuta terraform apply:

¿Captaste lo que pasó? ¿Notaste que el apply eliminó la regla de Bob?

En este ejemplo, no fue demasiado difícil verlo. Sin embargo, si el plan es mucho más largo, o si el cambio es menos obvio, entonces puede ser fácil pasarlo por alto.

Posibles soluciones ​

Hay algunas formas de evitar esto:

Usar terraform plan -out ​

Si Alice hubiera ejecutado terraform plan -out plan.tfplan, entonces cuando ejecutara terraform apply plan.tfplan vería:

El problema con esta solución es que ya casi nadie ejecuta terraform plan, ¡mucho menos terraform plan -out!

Es más fácil simplemente ejecutar terraform apply y los humanos tomarán el camino más fácil la mayoría del tiempo.

Envolver terraform apply para asegurar que esté actualizado con master ​

Otra posible solución es escribir un script wrapper que asegure que nuestra rama esté actualizada con master. Pero esto no resuelve el problema de que Bob ejecute apply localmente y todavía no haga merge a master. En este caso, la rama de Alice habría estado actualizada con master pero no con el estado más reciente al que se le hizo apply.

Ser más disciplinado ​

Qué pasaría si todos:

  • SIEMPRE crearan una rama, obtuvieran una revisión de pull request, hicieran merge a master y luego ejecutaran apply. Y además todos
  • SIEMPRE verificaran para asegurar que su rama estuviera rebasada desde master. Y además todos
  • SIEMPRE inspeccionaran cuidadosamente la salida de terraform plan y se aseguraran de que fuera exactamente lo que esperaban

...¡entonces no tendríamos un problema!

Desafortunadamente, esta no es una solución real. Todos somos humanos y todos vamos a cometer errores. Confiar en que las personas sigan un proceso complicado el 100% del tiempo no es una solución porque no funciona.

Problema central ​

El problema central es que todos están aplicando desde sus propias estaciones de trabajo y depende de ellos asegurarse de que estén actualizados y de que mantengan master actualizado. Esto es como si los desarrolladores desplegaran a producción desde sus laptops.

¿Qué pasaría si, en lugar de aplicar localmente, un sistema remoto hiciera los apply? ​

Por eso construimos Atlantis: un proyecto open source para automatización de Terraform por pull request. También podrías lograr esto con tu propio sistema de CI o con Terraform Enterprise. Así es como Atlantis resuelve este problema:

Cuando Alice hace su cambio, crea un pull request y Atlantis ejecuta automáticamente terraform plan y comenta en el pull request.

Cuando Bob hace su cambio, crea un pull request y Atlantis ejecuta automáticamente terraform plan y comenta en el pull request.

Atlantis también bloquea el directorio para asegurar que nadie más pueda ejecutar plan o apply hasta que el plan de Alice haya sido eliminado intencionalmente o ella haga merge del pull request.

Si Bob crea un pull request para su cambio de emergencia, vería este error:

Alice puede entonces comentar atlantis apply y Atlantis ejecutará el apply por sí mismo:

Finalmente, ella hace merge del pull request y desbloquea la rama de Bob:

Pero ¿qué pasa si Bob ejecutó apply localmente? ​

En ese caso, Alice todavía está bien porque cuando Atlantis ejecutó terraform plan usó -out. Si Alice intenta aplicar ese plan, Terraform dará un error porque el plan fue generado contra un estado antiguo.

¿Por qué Atlantis ejecuta apply en la rama y no después de un merge a master? ​

Hacemos esto porque terraform apply falla con bastante frecuencia, a pesar de que terraform plan tenga éxito. Usualmente es por un problema de dependencia entre recursos o porque el proveedor cloud requiere un cierto formato o que se establezca un cierto campo. Independientemente de eso, en la práctica hemos encontrado que apply falla mucho.

Al bloquear el directorio, esencialmente estamos asegurando que la rama a la que se le hace apply sea "master" ya que nadie más puede modificar ese estado. Luego obtenemos el beneficio de poder iterar sobre el pull request y subir pequeñas correcciones hasta estar seguros de que el conjunto de cambios está apply. Si apply fallara después de hacer merge a master, tendríamos que abrir nuevos pull requests una y otra vez. Definitivamente hay una compensación aquí, sin embargo creemos que es la compensación correcta.

Conclusión ​

En conclusión, ejecutar terraform apply cuando trabajas con un equipo de operadores puede ser peligroso. Considera soluciones como tu propio CI, Atlantis o Terraform Enterprise para asegurar que siempre estés trabajando a partir del código más reciente al que se le hizo apply.

Si te gustaría probar Atlantis, puedes comenzar aquí: https://www.runatlantis.io/guide/

Copyright Atlantis a Series of LF Projects, LLC. Para los términos de uso del sitio web, la política de marcas y otras políticas del proyecto, consulta LF Projects, LLC Policies.