En entradas anteriores hemos visto como utilizar contenedores durante la ejecución de tu pipeline en Azure DevOps. Ahora vamos a ver como hacer que tu pipeline se ejecute dentro de un contenedor, utilizando la imagen que te interese. A esto lo llamamos "Container jobs", aquí podeis ver la documentación oficial.
Motivaciones
¿Por qué ejecutar la pipeline dentro de un contenedor?
"Nuestra pipeline puede necesitar software que no tenemos disponible en nuestros agentes"
Si usamos agentes hosteados, sabemos que no podemos personalizarlos, tienen instalado cierto software base y de ahí no nos podemos mover. No nos quedaría otra que instalar el software necesario en la propia pipeline, mediante scripts, lo que resultaría en pipelines más lentas, algo que no es deseable (ya hablaremos de ello en futuros post).
Por otro lado, si usamos agentes propios, podríamos personalizarlos, para que ya dispusiesen de ese software base que necesitamos, pero ¿y si esos agentes se usan para varias pipelines? Si cada una de ella tiene sus propios requerimientos, puede resultar en una cantidad de software grande a manejar, y lo peor: colisiones entre versiones de dicho software.
Debido a lo anterior, podemos hacer que uno o varios jobs de nuestra pipeline se ejecuten directamente en un contenedor cuya imagen podamos seleccionar (o incluso crear) de acuerdo a nuestras necesidades.
¿Cómo lo hacemos?
Empezamos definiendo el contenedor, basado en una imagen redis por ejemplo, para a continuación especificar que lo usaremos en nuestro job:
Al estar nuestro job ejecutandose en un contenedor que tiene un redis instalado, si lo necesitásemos por ejemplo para pruebas de integración, nos evitaríamos instalar esta dependencia.
Fijaos, el yaml completo de un ejemplo en el que lanzamos un ping a Redis sería este:
Como se puede ver, ya que disponemos de Redis en el contenedor donde nuestro job se ejecuta, podemos arrancarlo y lanzarle un ping.
¿Podemos usar nuestra propia imagen?
Claro, aquí la cosa empieza a ponerse muy interesante. Podemos crear una imagen docker y utilizarla para que nuestro job de Azure Pipelines corra en ella.
Imaginemos que necesitamos las siguientes herramientas en nuestro pipeline:
- Redis
- El sdk de .net 5
Podemos generar una imagen con un dockerfile así:
Una vez subida la imagen a un docker registry (yo he usado mi cuenta en DockerHub, y la he llamado snavarropino/agent-redis-net5), podemos usarla para ejecutar allí nuestro pipeline, en el que compilaremos una aplicación .net 5 y lanzaremos sus tests de integración, que utilizan Redis.
- Restaurar paquetes nuget
- Compilar la aplicación .net 5
- Levantar el Redis
- Ejecutar tests de integración (que usan Redis)
Si queréis ver como implemento este último ejemplo visitad este video en mi canal de YouTube:
Espero que os haya resultado de interés. Gracias!
Recursos:
Documentación oficila sobre Container Jobs: https://docs.microsoft.com/en-us/azure/devops/pipelines/process/container-phases?view=azure-devops
Repositorio con el código: https://dev.azure.com/sergionavarropino/Yaml-docker