Mostrando entradas con la etiqueta Azure Pipelines. Mostrar todas las entradas
Mostrando entradas con la etiqueta Azure Pipelines. Mostrar todas las entradas

domingo, 10 de enero de 2021

Service containers en Azure Pipelines, parte 3: comunicando contenedores

Hemos visto en esta entrada como podemos ejecutar contenedores en el ámbito de una pipeline, pero ¿y si levantamos varios contenedores y queremos que se comuniquen entre ellos?

Imagina levantar un contenedor con tu aplicación (un api por ejemplo), otro con un Redis (dependencia de la aplicación), y desde tu pipeline poder lanzar requests para realizar tests.

 

 

 

Podemos hacerlo haciendo uso de Azure Pipelines Service Containers, empecemos por definir nuestros contenedores como recursos de la pipeline


Como veís he mapeado puertos para los dos contenedores, además de indicar en una variable de entorno como la aplicación puede acceder al Redis (aquí tienes el código de la aplicación por si quieres echarle un ojo).

Con estos dos contenedores definidos, podríamos perfectamente lanzar una request a nuestra api, que haría uso del Redis para dar una respuesta. Es importante destacar que los contenedores se ejecutarán dentro de una docker network, mientras que el agente de Azure Pipelines no, lo que tiene implicaciones:

  •  Los contentedores se pueden comunicar entre si usando el nombre del servicio, y sin que sea necesario mapear puertos
  • El agente de Azure DevOps accede a los contenedores usando localhost y el puerto mapeado.

 Con lo anterior podríamos lanzar una request al api (localhost puerto 80) y ver que status code nos responde.


Si la respuestra no es un 200, el step fallará, y por tanto también fallará nuestro pipeline.

Fijaos que como decía el api podrá "hablar" con el Redis a través del nombre del servicio (redis en mi caso). Se hace a traves de la variable de entorno CacheConnection. Si tratásemos de acceder con localhost a redis desde el contenedor del api no llegaríamos.

Os dejo el fichero yaml completo.

Comunicando contendores con "Container jobs"

Veíamos tambien en entradas anteriores como ejecutar un job de nuestra pipeline dentro de un contenedor. Si ese fuese el caso habría que tener en cuenta un detalle:

El job se ejecuta en un contenedor que está en la misma docker network que los otros contenedores, por lo que:

  • Puede acceder a ellos usando el nombre del servicio
  • No es necesario mapear puertos

En este caso el yaml resultante difiere un poco, aquí os lo dejo:

 

En breve dejaré un video donde podréis ver en vivo todo esto :-)

Espero que os haya resultado de interés. Gracias!

Recursos:

Repositorio con el código: https://dev.azure.com/sergionavarropino/Yaml-docker

domingo, 27 de diciembre de 2020

Azure Pipelines Container Jobs

Use Azure Pipelines for Free with Self Hosted Agent! | by Aadesh Jain |  Medium

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.

  
Como puede verse, una vez definida la imagen donde se ejecutará el único job de nuetsra pipeline, los pasos que ejecutamos son:
  • 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

sábado, 12 de diciembre de 2020

Service containers en Azure Pipelines, parte 2

Después de lo expuesto en la entrada anterior (enlace), continuamos profundizando en los Services Container de Azure DevOps Pipelines.

 

Veíamos como podíamos ejecutar en contenedor en el agente de Azure Pipelines para, por ejemplo, ejecutar un Redis del que hiciesen uso nuestros test de integración. Sin embargo, ¿y si quisiéramos esos test de integración contra diferentes versiones de Redis?

 

Matrix strategy + service container

 

Empecemos por definir varios container resources, uno por cada versión de Redis que queramos ejecutar, en nuestro caso las versiones 4, 5 y 6. 

 

 

Ahora la estrategia matrix de azure pipelines (si no sabes que es echa un ojo a este enlace y este otro) hará su magia, ejecutando un job para cada valor pasado como variable a la "matrix".

 

Definiremos también un servicio, que usando el valor de la variable que nos pasa la estrategia matrix, "apuntará" a uno de los contenedores. El resultado es que en cada job ejecutaremos lo mismo (tests de integración por ejemplo), pero contra una versión de Redis diferente.


 Y con esto, solo queda usar el servicio para "atacar" a cada versión de Redis, así queda el pipeline completo:

 

 

Cuando se ejecuta el pipeline, veremos que los 3 jobs generados ejecutan lo mismo (en el ejemplo que estamos haciendo lanzar un ping a Redis, que contestará con un PONG

 

 

 

 

Si queréis verme hacer este ejemplo en vivo, os dejo un video en mi canal de YouTube:

 

 

 

Espero que os haya resultado de interés. Gracias!

Recursos: 

Documentación oficial sobre la estrategia Matrix:

https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema%2Cparameter-schema#strategies

Documentación oficial sobre Service Containers: 

https://docs.microsoft.com/en-us/azure/devops/pipelines/process/service-containers?view=azure-devops&tabs=yaml