Cómo Slack desarrolló su uso de Terraform

Slack recuerda cómo generalizó, con la ayuda de herramientas internas, el uso de Terraform en su infraestructura de nube.

Un poco de GCP, DigitalOcean, NS1… y mucho AWS. Esta es la infraestructura de Slack. La empresa lo gestiona con Terraform. Sus equipos técnicos retomaron la implementación de la herramienta .

Inicialmente, Slack solo usaba una cuenta de AWS. Con un archivo de estado por región y un archivo de estado separado para servicios globales como IAM y CloudFront. Los entornos de desarrollo y producción tenían la misma configuración.

A medida que se desarrolló la infraestructura, fue necesario crear cuentas dedicadas a equipos y servicios. Para implementar cambios combinados en archivos de estado, Slack configuró canalizaciones Jenkins de dos etapas (planificar, aplicar). En ese momento, el equipo de operaciones era responsable de la infraestructura, el código base de Terraform y los archivos de estado.

Hoy en día ya no existe un equipo central de operaciones. Un equipo de Cloud Foundations gestiona la plataforma Terraform. Ahora hay un archivo de estado por región en cada cuenta secundaria y siempre hay un archivo de estado separado para los servicios globales. Los servicios más grandes también pueden tener los suyos propios, para limitar la cantidad de recursos que un único archivo estatal tendría que gestionar. Todo se almacena en un depósito S3 con gestión de versiones. Los nodos de Jenkins dedicados a canalizaciones tienen las funciones de IAM necesarias para crear recursos en cuentas secundarias.

Para permitir a los ingenieros probar cambios y nuevos módulos, Slack les ha proporcionado una interfaz de usuario web para iniciar «box Ops». Más precisamente, instancias cuyo tamaño, región y capacidad de almacenamiento eligen. Replican el entorno de trabajo de Jenkins, pero solo tienen acceso de solo lectura a las cuentas de AWS.

Una actualización gradual de la versión desde Terraform 0.11

Inicialmente, Slack solo admitía una versión de Terraform (0.11). En 2019 actualizó sus archivos de estado para hacerlos compatibles con la versión 0.12. De uno a otro hubo cambios de sintaxis. El procedimiento duró un cuarto. En este contexto, desarrollamos un contenedor que verificaba, en cada archivo de estado, la versión.tf y seleccionaba el binario de Terraform en consecuencia.

Slack permaneció en Terraform 0.12 durante casi dos años. Luego decidió actualizar a la versión 0.13. Y, al mismo tiempo, actualizar el proveedor de AWS (de la versión 3.74.1 a la versión 4.x).

Para poder implementar múltiples versiones de binarios y complementos y seleccionarlos según los archivos de estado, cada cuadro recibió un archivo de configuración que especificaba la versión de Terraform. Y el contenedor se actualizó.

Terraform 0.13+ le permite integrar varias versiones del mismo proveedor en la carpeta de complementos . Esto facilitó la actualización del binario de Terraform y del proveedor de AWS en paralelo . Si una nueva versión de la primera provocó cambios importantes en un archivo de estado determinado, podríamos fijar la versión anterior mientras esperamos una solución.

Una vez que todos los archivos de estado se actualizaron a las últimas versiones del proveedor , Slack eliminó las versiones fijadas. Al mismo tiempo que se anima a los equipos responsables de sus servicios a no anclar versiones específicas, en la medida de lo posible.

De Bash to Go, la evolución de las herramientas internas

Para gestionar las actualizaciones de Terraform, se desarrolló internamente una herramienta. Para un estado dado,:

– Comprueba la versión actual
– Comprueba si hay cambios no aplicados
– Comprueba si el archivo de estado se utiliza como estado remoto (Terraform 0.12 no puede buscar estados remotos en archivos de estado de Terraform 0.13+)
– Comprueba si después de actualizar el archivo de estado se puede ejecutar un plano de terraforma

La herramienta era inicialmente un script Bash. Slack terminó sustituyendo un binario de Golang. Las bibliotecas hclsyntx, gohcl y terraform-exec simplificaron la lectura de la configuración, la carga de elementos en las estructuras de datos de Go y la realización de operaciones de planes. También hemos equipado este binario con capacidades como el control de árboles de dependencia de módulos.

Los archivos de estado y de módulo se encuentran en un único repositorio . Slack utiliza el archivo CODEOWNERS para asignar reseñas a los equipos.

Originalmente, para los módulos, usábamos una ruta relativa. Ventaja: pruebas más fáciles. Desventaja: el riesgo de romper otros archivos de estado usando el mismo módulo.
En este contexto, Slack a veces ha favorecido los caminos de GitHub. Esto le permitió vincular un archivo de estado a una versión de módulo específica. Contraparte: cada operación de plan o aplicación debe clonar todo el repositorio . Los hashes de Git tampoco son los más fáciles de leer y comparar.

Un esquema específico en nombre del cumplimiento

De ahora en adelante, se activa una canalización para cada cambio fusionado en el repositorio de Terraform . Los módulos actualizados se guardan en archivos comprimidos y se envían al depósito de S3 como una nueva versión. Van acompañados de un archivo versiones.json que contiene el historial del módulo. Y una herramienta tf-module-viewer que le permite enumerar las versiones.

Este enfoque solo se implementa para archivos estatales para los cuales existen requisitos de cumplimiento. Los demás todavía utilizan la técnica de la ruta relativa.

Al agregar un módulo al catálogo, una herramienta Terraform Smart Planner le pide al usuario que lo desancle para probar todos los archivos de estado que lo usan. Sin embargo, ningún mecanismo fuerza este enfoque, aunque un cambio puede romper un archivo de estado. Los usuarios sólo descubrirían esto después de actualizar la versión del módulo fijado. Aunque es fácil, la reversión sigue siendo un inconveniente. Y requiere cargar una versión corregida del módulo en el catálogo antes de intentar utilizarlo.

Para crear las canalizaciones, Slack utiliza una biblioteca interna (Groovy) y el complemento Jenkins Job DSL . Cuando un equipo crea un archivo de estado, crea una nueva canalización o la agrega a una canalización existente. Un enfoque posible al agregar un script DSL a una carpeta que Jenkins monitorea. Para facilitar las cosas, hemos agregado un programa que crea scripts a partir de archivos YAML.

En ductos, la operación del plan debe ocurrir antes de la aplicación. Esto implica primero fusionar los cambios en la rama maestra del repositorio de Terraform . Por lo tanto, no estamos a salvo de que un cambio no deseado bloquee el proceso. Aquí es donde entra en juego Terraform Smart Planner. Para cada cambio, busca los archivos de estado afectados, realiza una operación de plan en cada uno e integra el resultado en el PR. Misma operación al actualizar un módulo.
La integración de los resultados en el PR permite a los revisores ver a qué recursos afecta un cambio. Esto también les ayuda a descubrir cualquier archivo de estado afectado indirectamente. Fuente, Ed Silicon desde Francia, traducido al español(C.B.)

Ilustración © zeeika – Adobe Stock

Comparte la nota:

Artículos relacionados

Scroll al inicio