
[14/01/2021] En la última docena de años, hemos sido testigos de un cambio dramático de las bases de datos de propósito general (Oracle, SQL Server, etc.) a las bases de datos diseñadas específicamente (trescientas sesenta de ellas y contando). Ahora los lenguajes de programación parecen ir en la misma dirección.
A medida que los desarrolladores pasan a una infraestructura altamente elástica, impulsada por API (donde los recursos pueden vivir durante días en lugar de años), están construyendo infraestructura como código (IaC, por sus siglas e inglés). Pero cómo construir IaC, sigue siendo una pregunta abierta. Por una variedad de razones, el lugar obvio para comenzar era con lenguajes imperativos como C o JavaScript, diciéndole a un programa cómo lograr un estado final deseado.
Pero un nuevo modelo de lenguajes declarativos --como HCL de HashiCorp o Polar de Oso- han surgido, donde el desarrollador le afirma al programa cuál es el estado final deseado, sin preocuparse demasiado por cómo llega a ese estado. De los dos enfoques, la programación declarativa podría ser la mejor opción, resultando en un código más sencillo y seguro. Veamos por qué es así.
El porqué de la programación declarativa
Cuando le pregunté a Sam Scott, cofundador y CTO de Oso, si realmente necesitábamos otro lenguaje de programación, su respuesta fue "sí”. La versión más larga: "con los lenguajes imperativos, a menudo hay un desajuste entre el lenguaje y su propósito; es decir, estos lenguajes fueron diseñados para que las personas creen aplicaciones y scripts desde cero, en lugar de definir configuraciones, políticas, etc.”.
La introducción de nuevos lenguajes declarativos, como Polar de Oso, realmente puede salvarnos de la proliferación de los lenguajes, continuó Scott: "No se trata solo de introducir otro lenguaje para resolver un conjunto específico de problemas. Más bien, se trata de crear algo para evitar que las personas tengan que inventar su propio lenguaje una y otra vez para realizar algún tipo de lógica incorporada”.
Tomemos, por ejemplo, el código JSON escrito para la autorización de AppSync:
{
"version” : "2017-02-28”,
"operation” : "PutItem”,
"key” : {
"postId” : $util.dynamodb.toDynamoDBJson($context.arguments.id)
},
"attributeValues” : {
"Author” : $util.dynamodb.toDynamoDBJson($context.identity.username)
#foreach( $entry in $context.arguments.entrySet() )
#if( $entry.key !="id" )
,”${entry.key}” : $util.dynamodb.toDynamoDBJson($entry.value)
#end
#end
},
"condition” : {
"expression” : "attribute_not_exists(postId)”
}
}
Para lograr un equilibrio entre los datos y la lógica, el desarrollador ha escrito permisos de estilo comentario en línea en Apache Velocity Template Language. Este es solo un ejemplo del proceso por el que pasan los desarrolladores de gimnasia para intentar expresar la lógica de autorización ("authZ”) mediante una combinación de configuración estática y plantillas.
Pero, en realidad, no se trata de si debemos usar programación imperativa, enfatizó Jared Rosoff de VMware, en una entrevista. En cambio, "es una cuestión de 'actualmente no usamos un lenguaje de programación para expresar reglas de autorización, pero tal vez deberíamos...'”. Después de todo, usamos datos, no un lenguaje de programación, para expresar reglas de autenticación. Esto está bien, señala Rosoff, cuando sus reglas de autenticación son bastante simples. Básicamente, tiene una tabla de búsqueda que consulta cuando llega una solicitud para decidir si está autorizada o no.
Fácil y natural.
El imperativo puede no ajustarse a la IaC
Pero el ejemplo de AppSync anterior muestra cómo el enfoque imperativo orientado a datos se complica rápidamente. "Lo que comenzó como un documento JSON, relativamente simple, se convirtió en algo con ramificaciones, condicionales y variables”, continuó Rosoff. Al adoptar este enfoque, el desarrollador está tratando de recrear la semántica similar a un lenguaje dentro de la sintaxis de datos estáticos, lo que resulta en un "lenguaje de programación basura que tiene una sintaxis terrible, sin bibliotecas, sin depuradores, etcétera”. No es lo ideal.
Tampoco es conciso, afirma Scott. "Es difícil codificar su lógica de autorización en lenguajes tradicionales”, señala. "Hacerlo en un lenguaje declarativo de propósito especial, como Polar, es más expresivo y conciso”.
Además, como explicó Scott, existen muchos dominios problemáticos donde, si un desarrollador intentara codificar un proceso en Java o Python, requeriría miles de líneas de código, lo cual es un problema en sí mismo. Sin embargo, esto se vuelve más problemático al oscurecer la lógica empresarial real. Por el contrario, un lenguaje declarativo puede realizar el mismo trabajo, pero en decenas de líneas de código.
Entonces, en lugar de cambiar la sintaxis de configuración a lenguajes imperativos, afirma Rosoff, deberíamos usar pequeños programas para manejar authZ y funciones relacionadas. Hoy en día, existen muchos problemas de programación en los que usamos datos para configurar un sistema, pero podría tener más sentido usar un programa, según Rosoff. Para nombrar unos pocos:
- Autorización
- Plantillas de implementación (por ejemplo, Terraform, Ansible, etc.). "Cada uno de estos intenta crear construcciones similares a un lenguaje, dentro de los límites de un lenguaje de datos, con resultados terribles”. Pulumi ofrece un enfoque interesante para esto.
- Flujos de trabajo. Temporal es un ejemplo interesante de tomar lo que se habría hecho anteriormente en un lenguaje de flujo de trabajo de diagrama, y llevarlo a un formato de lenguaje de programación de propósito más general.
Libertad suficiente, con sencillez y seguridad
El truco, afirma Rosoff, es darle al programador suficiente lenguaje para expresar la regla de autorización, pero no tanta libertad como para que puedan romper toda la aplicación si tienen un error. ¿Cómo se determina qué idioma usar? Rosoff ofrece tres criterios de decisión:
- ¿El lenguaje me permite expresar la amplitud completa de programas que necesito para escribir? (En el caso de la autorización, ¿me permite expresar todas mis reglas de autenticación?)
- ¿El lenguaje es conciso? (¿Tiene menos líneas de código y es más fácil de leer y comprender que el equivalente de YAML?)
- ¿El idioma es seguro? (¿Evita que el programador introduzca defectos, incluso intencionalmente?)
Todavía tenemos mucho camino por recorrer para hacer de los lenguajes declarativos la respuesta fácil y obvia a la programación de infraestructura como código. Una razón por la que los desarrolladores recurren a lenguajes imperativos es que tienen enormes ecosistemas construidos a su alrededor con documentación, herramientas y más. Por lo tanto, es más fácil comenzar con lenguajes imperativos, incluso si no son ideales para expresar configuraciones de autorización en IaC.
También tenemos trabajo por hacer para que los lenguajes declarativos sean accesibles para los novatos. Esta es una de las razones por las que Polar, por ejemplo, intenta tomar prestada la sintaxis imperativa.
Sin embargo, dados los beneficios de un enfoque declarativo, puede que simplemente sea cuestión de tiempo hasta que se conviertan en estándar para IaC.
Basado en el artículo de Matt Asay (InfoWorld) y editado por CIO Perú