Skip to content

Azure Pipelines

Azure Pipelines es una herramienta para canalizar el proceso de las etapas y tareas de un despliegue continuo en las que pueden incorporarse otras herramientas o proveedores que intervienen en el desarrollo de software. Para definir la estructura de un canal se utilizan archivos con formato YAML.

Configuración inicial

Azure Pipelines forma parte de Azure DevOps y no requiere instalación local. Se accede desde https://dev.azure.com creando una organización y proyecto.

Estructura de Pipeline YAML

Un pipeline de Azure se define con la siguiente estructura:

yaml
trigger:
- main

pool:
  vmImage: 'ubuntu-latest'

stages:
- stage: Build
  jobs:
  - job: BuildJob
    steps:
    - script: echo "Building application"
      displayName: 'Build Step'

- stage: Test
  jobs:
  - job: TestJob
    steps:
    - script: echo "Running tests"
      displayName: 'Test Step'

- stage: Deploy
  jobs:
  - job: DeployJob
    steps:
    - script: echo "Deploying application"
      displayName: 'Deploy Step'

Veamos aspectos claves de un Pipeline:

  • Pipeline: Flujo completo de CI/CD
  • Stage: Etapa lógica (Build, Test, Deploy)
  • Job: Conjunto de pasos que se ejecutan en un agente
  • Step: Tarea individual (script, task, etc.)
  • Trigger: Evento que inicia el pipeline

Agentes

  • Microsoft-hosted agents: Agentes administrados por Microsoft
  • Self-hosted agents: Agentes propios en máquinas locales o VMs

Para instalar un agente auto hospedado (self-hosted) con Linux, podemos ejecutar:

bash
wget https://vstsagentpackage.azureedge.net/agent/3.232.0/vsts-agent-linux-x64-3.232.0.tar.gz
tar zxvf vsts-agent-linux-x64-3.232.0.tar.gz
./config.sh
./run.sh

Ejemplo práctico con Node.js

yaml
trigger:
- main

pool:
  vmImage: 'ubuntu-latest'

variables:
  nodeVersion: '18.x'

stages:
- stage: Build
  displayName: 'Build Stage'
  jobs:
  - job: Build
    displayName: 'Build Job'
    steps:
    - task: NodeTool@0
      inputs:
        versionSpec: '$(nodeVersion)'
      displayName: 'Install Node.js'
    
    - script: |
        npm install
        npm run build
      displayName: 'npm install and build'
    
    - task: PublishBuildArtifacts@1
      inputs:
        pathToPublish: 'dist'
        artifactName: 'webapp'

- stage: Test
  displayName: 'Test Stage'
  dependsOn: Build
  jobs:
  - job: Test
    displayName: 'Test Job'
    steps:
    - task: NodeTool@0
      inputs:
        versionSpec: '$(nodeVersion)'
    
    - script: |
        npm install
        npm test
      displayName: 'Run tests'
    
    - task: PublishTestResults@2
      inputs:
        testResultsFormat: 'JUnit'
        testResultsFiles: '**/test-results.xml'

- stage: Deploy
  displayName: 'Deploy Stage'
  dependsOn: Test
  condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
  jobs:
  - deployment: Deploy
    displayName: 'Deploy Job'
    environment: 'production'
    strategy:
      runOnce:
        deploy:
          steps:
          - download: current
            artifact: webapp
          - script: echo "Deploying to production"

Configuración de credenciales AWS

Para integrar con AWS, se configuran Service Connections:

  1. Ir a Project Settings > Service connections
  2. Crear nueva conexión tipo AWS
  3. Proporcionar Access Key ID y Secret Access Key
  4. Usar en el pipeline:
yaml
- task: AWSShellScript@1
  inputs:
    awsCredentials: 'AWS-Connection'
    regionName: 'us-east-1'
    scriptType: 'inline'
    inlineScript: |
      aws s3 ls
      aws ec2 describe-instances

Integración con Terraform

yaml
- stage: Infrastructure
  jobs:
  - job: Terraform
    steps:
    - task: TerraformInstaller@0
      inputs:
        terraformVersion: '1.5.0'
    
    - task: TerraformTaskV4@4
      inputs:
        provider: 'aws'
        command: 'init'
        workingDirectory: '$(System.DefaultWorkingDirectory)/terraform'
        backendServiceAWS: 'AWS-Connection'
        backendAWSBucketName: 'terraform-state-bucket'
        backendAWSKey: 'terraform.tfstate'
    
    - task: TerraformTaskV4@4
      inputs:
        provider: 'aws'
        command: 'plan'
        workingDirectory: '$(System.DefaultWorkingDirectory)/terraform'
        environmentServiceNameAWS: 'AWS-Connection'
    
    - task: TerraformTaskV4@4
      inputs:
        provider: 'aws'
        command: 'apply'
        workingDirectory: '$(System.DefaultWorkingDirectory)/terraform'
        environmentServiceNameAWS: 'AWS-Connection'
        commandOptions: '-auto-approve'

Variables y secretos

yaml
variables:
- group: 'production-variables'  # Variable group
- name: 'buildConfiguration'
  value: 'Release'

steps:
- script: |
    echo "Build configuration: $(buildConfiguration)"
    echo "Secret value: $(secretVariable)"  # From variable group
  env:
    SECRET_KEY: $(secretVariable)

Triggers y condiciones

yaml
# Trigger por branch
trigger:
  branches:
    include:
    - main
    - develop
  paths:
    include:
    - src/*
    exclude:
    - docs/*

# Trigger por Pull Request
pr:
  branches:
    include:
    - main
  paths:
    exclude:
    - README.md

# Condiciones en stages
- stage: Deploy
  condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))

Templates y reutilización

yaml
# azure-pipelines.yml
stages:
- template: templates/build-template.yml
  parameters:
    buildConfiguration: 'Release'
    nodeVersion: '18.x'

# templates/build-template.yml
parameters:
- name: buildConfiguration
  type: string
- name: nodeVersion
  type: string

stages:
- stage: Build
  jobs:
  - job: Build
    steps:
    - task: NodeTool@0
      inputs:
        versionSpec: '${{ parameters.nodeVersion }}'
    - script: npm run build --configuration=${{ parameters.buildConfiguration }}

¿Por qué continuar abordando Azure Pipelines?

Para resumir, Azure Pipelines nos ofrece...

  • Integración nativa: Con Azure DevOps y servicios Azure
  • Escalabilidad: Agentes paralelos ilimitados
  • Flexibilidad: Tanto YAML como interfaz visual
  • Ecosistema: Miles de extensiones disponibles
  • Plan Gratuito: Para repositorios públicos y uso limitado privado

Azure Pipelines ofrece una solución robusta para CI/CD con integración profunda en el ecosistema Microsoft y soporte extenso para tecnologías de terceros.