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'
