Azure DevOps Ephimeral Agents: Agentes de usar y tirar

Tiempo de lectura: 7 minutos
Imagen ornamental para el artículo "Azure DevOps Ephimeral Agents: Agentes de usar y tirar"

En la última entrada tocamos un tema un poco diferente ya que nos salimos de temas como entity framework core, código de alto rendimiento y la línea general del blog para hablar de un tema un poco más general como es el cómo controlar un ordenador utilizando simplemente la mirada.

Hoy toca volver a la carga con la temática habitual y les toca el turno a los agentes efímeros de Azure DevOps.

¿Qué es un agente efímero de Azure DevOps?

La primera pregunta que hay que resolver es obviamente que es un agente efímero de Azure DevOps, y la respuesta ya se puede intuir del título, un agente de usar y tirar. La idea es crear un agente que esté disponible para poder realizar un trabajo y al acabarlo se elimine.

Los agentes de Azure DevOps es el nombre con el que se conoce a las diferentes máquinas que están conectadas a la organización de DevOps y que son las encargadas de realizar los trabajos de integración y despliegue. A su vez, los agentes se organizan en grupos llamados pools

¿Por qué se puede querer un agente de usar y tirar?

La segunda pregunta que hay que responder es sin duda para que puede hacer falta algo así. Para ello hace falta conocer un poco el funcionamiento de los agentes de Azure DevOps.

Cuando tu creas una organización, automáticamente y sin que tengas que preocuparte de nada, se crean diferentes pools de agentes hospedados por Microsoft.

Esto se puede comprobar de manera sencilla yendo a las propiedades de la organización o a las de cualquier proyecto. Dentro de ellas hay un apartado específico para los pools de agentes donde se muestran los diferentes grupos de agentes disponibles.

La imagen señala el botón Agent pools dentro de las propiedades de la organización y muestra los dos pools que hospeda Microsoft que son Azure Pipelines y Default

Lo bueno de estos agentes hospedados por Microsoft es que no requieren de ningún preparativo ni mantenimiento, están listos para usar desde el primer momento y corren directamente sobre Azure. Si el software que traen instalado de serie es suficiente (que es lo habitual), puedes usarlos sin preocuparte de nada.

¿Entonces, dónde está el problema? Principalmente tienen 2 problemas:

  • Eres dependiente del software preinstalado
  • Todos los recursos que necesites deben ser accesibles desde internet

Para el primero de los problemas se puede buscar alguna solución como por ejemplo instalar tú mismo lo necesario en el agente dentro del propio pipeline. En cambio, el segundo caso es el que generalmente se vuelve un problema serio…

Imagina que durante el proceso de integración continua o para desplegar necesitas acceder a un recurso de una red privada. Al no tener ningún tipo de control sobre los agentes, no hay manera posible de conectarlo a la red privada y por tanto el agente no va a poder hacer su trabajo.

Hasta la llegada a Azure DevOps de los agentes efímeros, la única solución que nos quedaba era la de tener un agente dentro de la red privada. Esto va desde una máquina virtual hasta un pod de Kubernetes, sea el modelo que sea y se hospede donde se hospede, necesitabas crear el agente previamente y asociarlo a un pool para poder usarlo.

En honor a la verdad, existía alguna manera como cuenta Gisela Torres en su blog, que consistía en que tú mismo creases y destruyeses un contenedor en Azure Container Instances durante el pipeline.

La idea de estos agentes efímeros de Azure DevOps es que puedas crear un agente de un solo uso como un contenedor de Azure Container Instances dentro de la red privada, y a diferencia de la aproximación que nos ofrecía Gisela, se destruya solo al terminar independientemente todo. Esto es especialmente útil ya que garantiza la optimización de costes al evitar posibles problemas que impidan la destrucción del contenedor una vez acabado el trabajo.

Poniendo en marcha un agente efímero

Vale, ya tenemos claro el concepto sobre cuándo y por qué utilizar un agente efímero para Azure DevOps. ¿Cómo lo ponemos en marcha?

En primer lugar, hay que tener en cuenta que vamos a crear un agente en un contenedor Docker, por lo tanto, vamos a necesitar crear una imagen Docker y subirla a un repositorio. Para crear la imagen vamos a partir del Dockerfile base para agentes efímeros de Azure DevOps que podemos encontrar en su repositorio de Github. Estas imágenes base a diferencia de las habituales, añaden toda la infraestructura necesaria para parar el agente, desregistrarlo del pool, y borrar el contenedor automáticamente.

Una vez que tenemos la imagen subida a un contenedor, vamos a crear un pool especifico que será donde se registren las instancias de los agentes a medida que se vayan creando. Para eso basta con ir de nuevo a la sección Agent pool de las propiedades de la organización o del proyecto, y pulsar sobre el botón de ‘añadir pool’ en la parte superior derecha. Esto nos mostrará una pequeña ventana donde elegiremos el nombre del pool. Una vez creado, hay que recordar el nombre ya que lo necesitaremos más adelante.

Como último paso de configuración previa, vamos a tener que crear las dos conexiones de servicio que vamos a utilizar en caso de que no las tengamos ya, una será hacia el registro de imágenes de docker y la otra hacia la propia suscripción de Azure. Esto se puede conseguir desde el botón ‘nueva conexión de servicio’ en la sección de conexiones de servicio.

La imagen señala la sección de conexiones de servicio y el botón de crear nueva conexión de servicio

Aquí vamos a crear en caso de que no exista una conexión de tipo Azure Resource Manager hacia la suscripción y otra de Docker Registry hacia el registro donde está la imagen.

También es necesario que tengamos un token que tenga permisos para operar el grupo de agentes. Este es el mismo requisito que si estuviésemos creando una agente de Azure DevOps normal y lo podemos conseguir siguiendo la documentación oficial.

Por último pero no menos importante, vamos a necesitar instalar la tarea Ephemeral Pipelines Agents desde el marketplace. Una vez que lo tengamos, ya estamos listos para empezar a crear pipelines que utilicen agentes efímeros de Azure DevOps.

Crear un pipeline que utilice el agente efímero

Hemos llegado a la parte más fácil de todas, vamos a crear un pipeline multi etapa donde la primera etapa va a crear el agente efímero y la segunda va a realizar el trabajo dentro de nuestra red privada. Para eso basta con que creemos un pipeline con un yaml como este:

trigger: none

variables:
  # Nombre del grupo de recursos donde se creará el agente
  ResourceGroup: 'ephemeral-agents'
  # Nombre del grupo de recursos donde está la red privada
  vNetResourceGroup: 'ephemeral-agents'
  # Nombre de la red privada
  vnetName: private-network
  # Nombre de la subnet donde se conectará el agente
  subnetName: 'agents'
  # Localización
  location: 'West Europe'
  # Nombre del ACR
  acrName: fixedbuffer
  # Nombre de la imagen del agente
  imageName: $(acrName).azurecr.io/agent
  # Nombre de la conexión de servicio de ARM
  azureSubscription: 'Visual Studio Enterprise'
  # Nombre de la conexión de servicio de Docker Registry
  containerRegistryConnection: 'fixedbuffer'
  # Nombre del pool de agente
  agentpool: ephemeral
  # Token para el agente, puede ser $(System.AccessToken) si tiene suficientes permisos
  accessToken: 'accessToken'


stages:
- stage: PrepareAgent
  jobs:
  - job: PrepareAgent
    displayName: Prepare Agent
    pool: Hosted Ubuntu 1604
    steps:
    - task: AzureContainerAgentCreate@0
      displayName: 'Azure Container Create for pool ephemeral'
      inputs:
        azureSubscription: $(azureSubscription)
        resourceGroupName: $(ResourceGroup)
        location: $(location)
        azureDevOpsToken: $(accessToken)
        containerRegistry: $(containerRegistryConnection)
        imageName: $(imageName)
        agentPool: $(agentpool)
        agentPrefix: 'ephemeral-'
        vnetResourceGroupName: $(vNetResourceGroup)
        vnetName: $(vnetName)
        subnetName: $(subnetName)

- stage: Deploy
  jobs:
  - deployment: Deploy
    environment: 'Production'
    displayName: Deploy Files
    pool: ${{variables.agentpool}}
    strategy:
      runOnce:
        deploy:
          steps:
          - script: echo 'Hello World'

Sí todo va bien, cuando ejecutemos este pipeline debería crearse un agente en la suscripción el cual va a ejecutar el stage de Deploy (en este caso dirá Hello World) y una vez termine se borrará el agente.

Conclusión

La posibilidad de utilizar agentes efímeros en Azure DevOps simplifica enormemente la infraestructura necesaria para ciertos despliegues donde las redes privadas requerirían de levantar una máquina exclusivamente para esa labor. Pero ojo, no es oro todo lo que reluce, hay que evaluar si realmente compensa utilizar este modelo ya que, si por ejemplo hacemos muchos despliegues a día, o son despliegues que duran varias horas, quizás no sea una opción interesante a nivel de costes. En los proyectos en los que trabajo por ejemplo suele haber un cluster de kubernetes conectado a esa red privada y resulta mucho más interesante tener un pod desplegado dedicado a esa labor.

Pese a todo, si se hacen despliegues una o dos veces al día y no son especialmente lentos, la opción de utilizar agentes efímeros puede ser una muy buena solución para evitar tener que preocuparse de mantener máquinas y librarse de algunos costes. Cuanto menos, son una herramienta muy interesante a tener en cuenta 🙂

Deja un comentario