domingo, 28 de julio de 2019

Master en sintaxis de la configuración yaml en [Google Cloud Build]




La plataforma de automatización de Cloud Build de Google se basa en una serie de pasos de "constructores" en contenedores, especificados en un archivo de configuración YAML.

Para cada paso, GCB arranca un contenedor Docker y ejecuta un comando específico dentro del contexto de ese contenedor, como Gradle, gcloud o Wget. Puede pasar uno o más argumentos a ese comando usando el campo args en su archivo cloudbuild. yaml.

Esta sintaxis facilita la puesta en marcha de un proceso de compilación básico. Pero a medida que agrega complejidad a su proceso , puede encontrar que su YAML se vuelve difícil de analizar y mantener, o incluso que hay cosas que necesita hacer que simplemente no se pueden expresar. 

En esta publicación, mostraremos formas alternativas de escribir su configuración de creación en el Cloud de estos yaml. Al aplicar estas best practices, tendrá archivos de configuración más legibles y mantenibles. Aún mejor, puede aprovechar el poder oculto de Cloud Build para crear tus pipelines avanzadas con tus  CI / CD.


Como ejemplo, realizaremos un paso de compilación que recupera texto de una API remota y lo imprime en la consola. Empecemos con la versión más simple de la configuración:

Sintaxis simple


steps:
- name: 'gcr.io/cloud-builders/curl'
  args: ['https://pets.doingdevops.com/pet','-s','--max-time','10']

Esta es la sintaxis más común que se encuentra en la documentación, y suele ser el la forma correcta para comenzar.

Práctica recomendada: use esto para trabajos simples: es conciso y fácil de leer.

Sintaxis expandida (collection style)


También funciona si agregamos saltos de línea a la sintaxis simple:

steps:
- name: 'gcr.io/cloud-builders/curl'
  args:
    [
      'https://pets.doingdevops.com/pet',
      '-s',
      '--max-time', '10', # related args on one line
    ]

Al agregar saltos de línea, dejamos espacio para argumentos largos, y hacemos que sea más fácil ver dónde termina un argumento y comienza el siguiente. Esto es especialmente útil cuando se usan variables o estructuras de datos dentro de argumentos, que pueden ser difíciles de leer fácilmente.

Sin embargo, la regla de un argumento por línea no se aplica en realidad. Por lo tanto, si varios argumentos están relacionados, se pueden agrupar una línea. En este ejemplo, los argumentos --max-timeand 10 están en la misma línea, para hacer evidente que uno se refiere al otro.

Best practice: use esta sintaxis cuando la sintaxis básica se vuelva complicada: muchos argumentos, argumentos largos, complejidad dentro de los argumentos, etc. !Cuidado con la gestión de las comas finales¡

Sintaxis expandida (estilo de lista)

Alternativamente, podemos escribir el paso usando una lista YAML, con un argumento por línea, prefijado con guiones. Los argumentos pueden no estar citados, pero eso es una mala idea; es muy difícil leer un argumento como - -s: ¿ese guión-espacio-guión? o espacio-dash-dash? o…?
steps:
- name: 'gcr.io/cloud-builders/curl'
  args:
  - 'https://pets.doingdevops.com/pet'
  - '-s'
  - '--max-time'
  - '10'

Si bien esto es similar a la "sintaxis expandida (estilo de colección)", tiene algunas desventajas:

  1. Tener un guión por argumento reduce la legibilidad, especialmente porque muchos argumentos tendrán sus propios guiones;
  2. No puedes agrupar múltiples argumentos en una sola línea
  3. Es más difícil convertir desde la "sintaxis simple".

Mejores Prácticas: No usar. (Prefiere "estilo de colección".)


Breakout syntax

Cada constructor tiene un punto de entrada predeterminado, que generalmente se relaciona con el propósito de ese constructor. Por ejemplo, el punto de entrada del constructor Gradle es gradle. 

Cuando se invoca un paso de compilación de gradle, el comando de gradle se ejecuta en el contenedor, con todo en la matriz de argumentos que se pasa como argumentos a Gradle.

Pero no estamos limitados solo al comando predeterminado: podemos "romper" y ejecutar cualquier comando disponible en el contenedor, simplemente especificando un punto de entrada alternativo.

La mayoría de los constructores han instalado bash, lo que nos brinda la máxima flexibilidad para hacer todo lo que deseamos dentro de nuestro paso. Esta es la misma operación, pero invocando a bash directamente:
steps:
- name: 'gcr.io/cloud-builders/curl'
  entrypoint: 'bash'
  args:
  - '-c' # pass what follows as a command to bash
  - |
    curl -s 'https://pets.doingdevops.com/pet' --max-time 10

Aquí, se usa una sintaxis de bloque YAML (el argumento está precedido por "|"), por lo que podemos pasar una cadena multilínea sin comillas como el comando. ¿Y qué hemos logrado exactamente? ¡Nada! Esto sigue haciendo lo mismo que el ejemplo "simple". Pero ahora tenemos todo el poder para ejecutar comandos bash arbitrarios. Así que podemos hacer más. Mucho más…

Supongamos que la API remota es inestable; a veces falla En ese caso, queremos volver a intentarlo hasta que tenga éxito. Aquí hay un ejemplo que usa múltiples comandos y lógica condicional para asegurar que obtengamos una respuesta válida:
steps:
- name: 'gcr.io/cloud-builders/curl'
  entrypoint: 'bash'
  args:
  - '-c'
  - |
    PET="$$(curl -s https://pets.doingdevops.com/pet_flaky --max-time 10)"
    while [ "$$PET" == "ERROR" ] ; do
      echo "Error: API failed to respond with a pet! Try again..."
      PET="$$(curl -s https://pets.doingdevops.com/pet_flaky --max-time 10)"
  done
  echo "Success! $${PET}"

Tenga en cuenta el uso de signos de dólar dobles ($$) como caracteres de escape. Esto garantiza que Cloud Build los pasará al contenedor, en lugar de interpretarlos como sustituciones.

Al anular el punto de entrada y unir los comandos de bash, podemos hacer todo lo posible dentro de los límites de este contenedor . Y si necesita hacer algo que no esté disponible en un constructor existente, puede crear su propia imagen de constructor personalizada; asegúrese de incluir un shell (por ejemplo, bash) si planea usar la sintaxis de "breakout".

¿Qué es algo interesante que hayas hecho con Cloud Build? Deja una nota en los comentarios!

Los archivos de configuración de ejemplo, y la fuente de los servicios API remotos, se pueden encontrar en github.com/davidstanke/gcb-syntax-blog.

No hay comentarios:

Publicar un comentario

Nota: solo los miembros de este blog pueden publicar comentarios.