Muy buenas, soy Miguel y en esta ocasión les traigo un artículo.
En Opendoor, los datos son fundamentales para todo lo que hacemos. De ello se deduce, entonces, que la plataforma que gestiona todos esos datos es de misión crítica.
Nuestra plataforma de análisis se basa en Snowflake y ejecuta cientos de miles de consultas por día, respondiendo preguntas y procesando terabytes de datos para nuestros usuarios.
Esta publicación describe cómo y por qué pasamos de configurar nuestra cuenta Snowflake manualmente a configurarla a través de Terraform, una herramienta de infraestructura como código.
Cubriremos cómo trabajamos alrededor de algunas de las limitaciones de Terraform para traer cientos de recursos de Snowflake preexistentes bajo la administración de Terraform, sin tiempo de inactividad y sin necesidad de una configuración escrita a mano.
Índice
Antecedentes
Snowflake se describe a sí mismo como una plataforma de «Gestión casi cero», con un mínimo de botones para girar. Ciertamente es cierto que, en comparación con algunos de sus competidores, Snowflake requiere muy pocos ajustes para lograrlo. Rendimiento estelar.
Sin embargo, incluso si no requiere mucho ajuste del rendimiento, cualquier plataforma de datos suficientemente compleja gestionará cientos o incluso miles de objetos.
En Snowflake, algunos de los objetos clave incluyen almacenes, usuarios, roles, bases de datos, esquemas, tablas y vistas, sin mencionar las concesiones que controlan el acceso a esos objetos.
La creación, modificación y eliminación de estos objetos Snowflake se puede hacer en Snowflake interfaz web o corriendo SQL de copo de nieve.
En el mejor de los casos, escribimos runbooks con fragmentos de código SQL de plantilla; en el peor de los casos, el proceso de configurar algún aspecto de nuestro relato fue un “conocimiento tribal” que vivió solo en la cabeza de un ingeniero.
Esto nos dejó con una cuenta de Snowflake que funcionaba bien, pero era difícil de ajustar y aún más difícil de entender.
Problemas
Nuestra cuenta de Snowflake hecha a mano tuvo algunos problemas:
- Auditabilidad: ¿A qué usuarios se les asignó qué roles? ¿A qué conjuntos de datos podría acceder cada rol? Responder a estas preguntas fue difícil y requirió un usuario de Snowflake con muchos privilegios.
- Estandarización: ¿Qué rol / usuario debería usarse para crear nuevos objetos? El rol utilizado por el creador es importante porque ese rol se convierte en el propietario del objeto y define los privilegios predeterminados sobre el objeto. La creación manual de objetos es propensa a errores, ya que un ingeniero podría crear accidentalmente un objeto utilizando la configuración de su última sesión no relacionada.
- Colaboración: Un usuario privilegiado que modifica un recurso en la consola de Snowflake o ejecuta SQL lo hace en el vacío. Si bien confiamos en que nuestros compañeros de equipo sepan lo que están haciendo, preferimos poder tener un proceso formal de revisión del código de estos cambios.
- Historia: Técnicamente, todos los cambios de cuenta se registran y se puede acceder a ellos a través del
QUERY_HISTORY
ver. Sin embargo, analizar esos registros requiere conocimientos de SQL y Snowflake, y preferiríamos que los cambios se controlen por versiones con algo universal como Git. - Velocidad: Es molesto y lento cambiar estos recursos a mano. El tiempo de nuestros ingenieros es valioso; no debemos gastarlo en tareas tediosas como escribir el comando SQL para ajustar el tiempo de espera de consulta predeterminado de un almacén determinado.
Préstamo de DevOps
: infraestructura como código
Afortunadamente, el mundo de DevOps tiene una solución a estos problemas: Infraestructura como código.
Code (IaC)
es que el estado de los recursos de la nube debe definirse mediante archivos de configuración (normalmente registrados en un repositorio controlado por versiones).
Los cambios en los recursos se realizan actualizando esos archivos de configuración y «implementando» el cambio usando una CLI
. (Es una buena práctica ejecutar esto en una canalización de CI / CD
).
Cuando usa IaC
, puede asimilar el estado de sus recursos simplemente leyendo los archivos de configuración, y puede colaborar en los cambios en sus recursos de la misma manera que lo haría con otro código: con historial de git
, solicitudes de extracción, revisiones de código, etc.
Las herramientas de IaC
se centraron originalmente en administrar los servidores en un entorno de computación en la nube, pero hoy puede administrar la configuración de básicamente cualquier herramienta de terceros que use su equipo.
Considere nuestro caso de uso de Snowflake: no necesitamos configurar las máquinas virtuales reales que usa nuestra cuenta ¡Snowflake lo hace por nosotros! pero sí queremos administrar recursos clave de Snowflake como Usuarios y Bases de datos.
Existen varias herramientas de IaC
(Cocinero, Marioneta, Ansible), pero nos decidimos por Terraform por dos razones:
- Opendoor ya estaba usando Terraform para administrar nuestros recursos de AWS, por lo que teníamos ingenieros con experiencia, y un paso de lanzamiento de Terraform ya se incluía de forma predeterminada en las canalizaciones de
CI / CD
de todos los servicios. - Terraform es compatible con los principales proveedores de la nube (AWS, GCP, etc.) listos para usar; para todo lo demás, deberá instalar Proveedores comunitarios. Hay un par de proveedores de Terraform Snowflake de código abierto; nos decidimos por la Iniciativa Chan Zuckerberg (CZI) Proveedor de copos de nieve, ya que su repositorio de Github tuvo la mayor actividad, y las confirmaciones recientes mostraron que se está manteniendo y desarrollando activamente.
Terraform: una breve introducción
No cubriremos Terraform con gran detalle aquí, pero hay algunos conceptos clave que deberá comprender:
El lenguaje de configuración de Terraform declara recursos que se asignan a los componentes de su infraestructura. Por ejemplo, un usuario de Snowflake está definido por el snowflake_user
recurso en el proveedor CZI.
La configuración de estos recursos vive en .tf
archivos de configuración – un dado .tf
archivo puede albergar muchas definiciones de recursos, y puede tener muchas .tf
archivos en su directorio terraform.
El.tfstate
archivo representa el estado actual de su infraestructura «en vivo». Generalmente no edite este archivo a mano; en cambio, los comandos de la CLI de Terraform lo modificarán por usted.
Corriendo terraform plan
comparará su actual archivos .tf
a tu .tfstate
y generar un informe que describa cómo la configuración declarada por sus archivos .tf
difiere del estado de su infraestructura de producción actual.
Corriendo terraform apply
Realmente realiza los cambios descritos por terraform plan
en su infraestructura en vivo. ¡Ten cuidado con este!
Terraformación de una cuenta Snowflake existente
Permítanme hacer una pausa aquí y ofrecer algunos consejos que me han costado mucho ganar: si son un equipo de datos que está configurando una nueva cuenta de Snowflake, deje todo e instale Terraform y el proveedor CZI Snowflake.
Es mucho, mucho más fácil usar Terraform desde el día 1
, haciendo que el 100%
de los cambios de su cuenta a través de cambios en sus archivos .tf
.
No usamos Terraform desde el principio; los cambios en los recursos de nuestra cuenta se realizaron manualmente en la consola de Snowflake o usando Snowflake SQL.
Para poner nuestra cuenta de Snowflake bajo la administración de Terraform, necesitábamos agrupar cientos de Usuarios, Almacenes, Esquemas y otros objetos preexistentes en nuestro .tf
y archivos .tfstate
.
El proceso de actualización de Terraform en una cuenta de Snowflake existente tuvo dos desafíos principales:
El archivo .tfstate
está diseñado para mantenerse sincronizado con su infraestructura real. Por lo tanto, el primer paso para poner una cuenta de Snowflake existente bajo la administración de Terraform es generar un archivo .tfstate
que refleja el estado actual de sus recursos.
Afortunadamente, Terraform proporciona una solución aquí: terraform import
atrae los recursos existentes a su archivo .tfstate
. El proveedor de CZI Snowflake admite este comando. Por ejemplo, puede importar su papel PUBLIC
así:
$ terraform import snowflake_role.public "PUBLIC"
Desafortunadamente, terraform import
solo puede importar un recurso a la vez; no hay forma de importar por lotes todos los recursos en un proveedor.
Terraform import
es útil, pero solo resuelve la mitad del problema. Atrae los recursos existentes a su .tfstate
, pero no genera definiciones de recursos en su archivo .tf
.
De hecho, no podrá importar un recurso a menos que ya exista una definición de recurso coincidente en un archivo .tf
.
Esto significa que cada vez que terraform import
un recurso existente, primero tienes que a mano escriba una definición de recurso para ese recurso. Desde el Terraform docs:
Si bien esto puede parecer tedioso, aún ofrece a los usuarios de Terraform una vía para importar recursos existentes.
Dado que para el caso de uso de Snowflake, una cuenta preexistente puede tener cientos o miles de recursos definidos, ¡tedioso es correcto!
Snowglobe
: Importación programática de recursos de Snowflake
Afortunadamente, descubrimos una manera de evitar correr terraform import
cientos de veces y escribiendo miles de líneas de definiciones de recursos a mano.
Nuestra solución a estos problemas es snowglobe
, un paquete interno de Python que escribimos que genera de manera programática definiciones de recursos para cada recurso Snowflake existente, agregando el resultado a un archivo .tf
y llamada terraform import
para llevar el recurso al archivo .tfstate
.
La clave de este flujo de trabajo es que todos los objetos Snowflake de una cuenta se pueden recuperar mediante programación utilizando un usuario Snowflake privilegiado y Snowflake SQL.
Podemos usar eso para nuestra ventaja al automatizar el proceso de obtener el estado actual de un recurso, generar un bloque de configuración de recursos y ejecutar terraform import
para el objeto.
Consideremos a los usuarios como ejemplo:
- En
snowglobe
, escribimos una clase para cada tipo de recurso a importar: en este casoCZISnowflakeUser
. Los atributos de un objeto de esta clase coinciden con las propiedades del tipo de recurso relevante del proveedor de Terraform, en este casosnowflake_user
. (name
,default_role
, etc.):
class CZISnowflakeUser: def __init__( self, name: str, comment: str = None, default_namespace: str = None, ... ): self.name = name self.comment = comment self.default_namespace = default_namespace ... def alias_resource(self): return f"{self.name.lower()}" def snowflake_provider_resource(self): return "snowflake_user"
- Utilizando la conector Snowflake Python, podemos ejecutar
SHOW USERS
y cargue todos los usuarios de Snowflake en un marco de datos de Pandas. - La clase
CZISnowflakeUser
incluye un método para analizar una fila de ese marco de datos en un objetoCZISnowflakeUser
. - El analizado el objeto
CZISnowflakeUser
se pasa a través de un genérico analizadorobj_to_terraform
, que convierte el objeto en una cadena de definición de recursos compatible con Terraform y la agrega al archivousers.tf
, por ejemplo
resource "snowflake_user" "example_user" { name = "EXAMPLE_USER" comment = "This is an example user" default_namespace = "PUBLIC" default_role = "PUBLIC" default_warehouse = "DEMO_WH" disabled = false login_name = "EXAMPLE_USER" must_change_password = false }
- Una
terraform import
se genera y ejecuta el comando, importando el usuario en el.tfstate
:
terraform import snowflake_user.example_user "EXAMPLE_USER"
Las clases / análisis de todos los tipos de recursos se empaquetan en una sola función main
que llama a todo y genera el final archivo .tfstate
y el correspondiente archivo .tf
.
Estos archivos representan el estado actual de la cuenta Snowflake existente en el lenguaje Terraform y se pueden usar como punto de partida para un proyecto Snowflake completamente administrado por Terraform.
Todos los cambios posteriores al archivos .tf
y un correspondiente terraform apply
realmente hará esos cambios en el recurso Snowflake.
Resultados y próximos pasos
Con snowglobe
, pusimos con éxito nuestra cuenta Snowflake existente bajo la administración de Terraform.
Generamos programáticamente miles de líneas de configuración e importamos cientos de recursos de Snowflake sin tener que ejecutarlos manualmente terraform import
una vez.
snowglobe
, .tfstate
y .tf
generados, pudimos comenzar a realizar todos los cambios posteriores en estos recursos a través de Terraform, sin tiempo de inactividad o interrupción del usuario.La gestión de la configuración de nuestra cuenta Snowflake a través de Terraform ha resuelto los problemas descritos anteriormente, pero aún queda trabajo por hacer.
Hay algunos recursos adicionales de Snowflake que queremos implementar en snowglobe
y poner bajo la gestión de Terraform, el más importante de los cuales es Políticas de red.
El proveedor de CZI Políticas de red actualmente no es compatible, por lo que estamos planeando desarrollar la función y contribuir con ella al proyecto.
¿Suena como algo en lo que estarías interesado en trabajar? Fueron contratando Buscamos compañeros de equipo talentosos y apasionados para ayudar a construir el futuro de los bienes raíces.
Gracias por leer este artículo.
Añadir comentario