Crear self-hosted-Agents en w11 con Azure DevOps

David

En proyectos de CI/CD con Azure DevOps, una de las decisiones clave es elegir dónde correr tus pipelines. Por defecto, Microsoft ofrece Microsoft-hosted agents, que son máquinas virtuales efímeras mantenidas en la nube. Sin embargo, cuando necesitamos más control, personalización o acceso a recursos locales, la mejor opción es configurar self-hosted agents.

¿Qué es un self-hosted agent?

Un self-hosted agent es una máquina (física o virtual) administrada por ti, donde instalas el software de agente de Azure DevOps.

Pasos para crear un Agent Pool en Azure DevOps

1) Ingresar a Azure DevOps, click en seccionar personal access tokens, crear tocken, guardar el token generado ya que no se podre visualiza el valor de nuevo


2)Abrir una terminal de ubuntu



3)En Azure DevOps Ingresar a Organization Settings>Agent pools>Default



4)Click en: Agents>new Agents

5)Copiar el link de descarga del get the agent y descargar en la terminal de ubuntu de w11, seguir los comandos que se muestran


6)tendrá un mensaje algo similar a:

7)En Azure DevOps Validar la conexión

8)Probar el agente en un proyecto, ejecutando el pipeline con el nuevo agente

9)Código de Azure-pipelines.yml usado

trigger:
- main

pool:
  name: Default
  demands:
  - agent.name -equals linux-agent
  - maven # Requerido por la tarea Maven 

steps:
# 1. INSTALACIÓN DE DEPENDENCIAS (Java, Maven, etc.)
- script: |
    echo "======================================================"
    echo "1. Instalando OpenJDK 11 y Maven"
    echo "======================================================"
    
    # 1.1 Actualizar la lista de paquetes
    sudo apt update
    
    # 1.2 Instalar OpenJDK 11 (requerido por el proyecto)
    sudo apt install openjdk-11-jdk -y 
    
    # 1.3 Instalar Maven
    sudo apt install maven -y
    
    echo "======================================================"
    echo "2. Configurando JAVA_HOME para el Job"
    echo "======================================================"
    
    # Busca la ruta del JDK 11
    JDK_PATH=$(readlink -f /usr/bin/java | sed "s:bin/java::")
    
    # Exporta JAVA_HOME para que la tarea Maven@3 lo use
    echo "##vso[task.setvariable variable=JAVA_HOME;]$JDK_PATH"
    echo "##vso[task.setvariable variable=JAVA_HOME_11_X64;]$JDK_PATH"
    
    echo "JAVA_HOME configurado a: $JDK_PATH"
    
  displayName: 'Configuración Manual de JDK y Maven'

# 2. INSTALACIÓN DE TRIVY
- script: |
    echo "======================================================"
    echo "3. Instalando Trivy (con sudo para permisos)"
    echo "======================================================"
    # Uso de sudo para tener permisos de escritura en /usr/local/bin
    curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sudo sh -s -- -b /usr/local/bin
  displayName: 'Instalar Trivy'

# 3. EJECUTAR MAVEN PACKAGE
# Como configuramos JAVA_HOME en el paso 1, la tarea Maven@3 lo encontrará.
- task: Maven@3
  inputs:
    mavenPomFile: 'pom.xml'
    mavenOptions: '-Xmx3072m'
    # 'JDKVersion' le dice a la tarea que busque una variable JAVA_HOME_X_X64
    javaHomeOption: 'JDKVersion'
    jdkVersionOption: '1.11'
    jdkArchitectureOption: 'x64'
    publishJUnitResults: true
    testResultsFiles: '**/surefire-reports/TEST-*.xml'
    goals: 'package'
  displayName: 'Ejecutar Maven Package'

# 4. TRIVY SCAN Y FALLO
- script: |
    echo "======================================================"
    echo "4. Escanear Sistema de Archivos con Trivy"
    echo "======================================================"
    
    # Ejecuta el escaneo
    trivy fs --severity HIGH,CRITICAL . --format json -o trivy-results.json
    
    # Verifica si hay vulnerabilidades CRÍTICAS
    if grep -q '"Severity": "CRITICAL"' trivy-results.json; then
      echo "##[error]Vulnerabilidades CRÍTICAS encontradas. Fallando el Pipeline."
      exit 1
    fi
  displayName: 'Escanear con Trivy y Fallar si es Crítico'

# 5. PUBLICAR ARTEFACTOS
- task: PublishBuildArtifacts@1
  inputs:
    PathtoPublish: 'trivy-results.json'
    ArtifactName: 'TrivyResults'
    publishLocation: 'Container'
  displayName: 'Publicar Resultados de Trivy'

10) En Azure DevOps ingresar a Browse marketplase

11)Buscar y descargar Sarif Sast, esto para publicar los resultados del análisis de código estático con trivy

12)Optimizar el código. una vez ejecutado el código en nuestra maquina local no hay que seguir descargando las herramientas como java, trivy, etc, en cada ejecución del pipeline, esto implica una mejora en tiempos

trigger:
- main

pool:
  name: Default
  demands:
  - agent.name -equals linux-agent
  - maven 

steps:

- script: | 
    JDK_PATH=$(readlink -f /usr/bin/java | sed "s:bin/java::")
    echo "##vso[task.setvariable variable=JAVA_HOME_11_X64;]$JDK_PATH"   
  displayName: 'Configuración Manual de JDK/Maven'

- task: Maven@3
  inputs:
    mavenPomFile: 'pom.xml'
    mavenOptions: '-Xmx3072m'
    javaHomeOption: 'JDKVersion'
    jdkVersionOption: '1.11'
    jdkArchitectureOption: 'x64'
    publishJUnitResults: true
    testResultsFiles: '**/surefire-reports/TEST-*.xml'
    goals: 'package'
  displayName: 'Ejecutar Maven Package'

# 4. TRIVY SCAN 
- script: |
    /usr/local/bin/trivy fs --severity HIGH,CRITICAL . --format sarif --output trivy-results.sarif
  displayName: 'Escanear con Trivy y Generar SARIF'

# 5. PUBLICAR RESULTADOS SARIF
- task: PublishBuildArtifacts@1
  inputs:
    PathtoPublish: 'trivy-results.sarif' 
    # CLAVE: Usamos el ArtifactName que la extensión SARIF espera
    ArtifactName: 'CodeAnalysisLogs' 
    publishLocation: 'Container'
  displayName: 'Publicar Resultados SARIF'


David Guzmán López

Ingeniero Electrónico

Electronic Engineer | DevOps Engineer | SRE | Cloud Engineer | Infrastructure Engineer