← Volver al inicio

Pipeline DevOps del Futuro: GitOps, Terraform y Azure DevOps en 2026

¿Qué es un pipeline DevOps? (explicación sencilla)

Un pipeline DevOps es como una cadena de montaje automática para el software: toma el código, lo prueba, lo empaqueta y lo despliega en la nube, todo sin intervención manual.

GitOps es una forma moderna de gestionar todo esto usando Git (una herramienta para guardar y versionar código) y automatización.

En este artículo, te explico cómo funciona un pipeline DevOps moderno usando Terraform y Azure DevOps, aunque nunca hayas trabajado con estas herramientas.

Arquitectura del Pipeline

1. Estructura del Repositorio

Esta estructura organiza tu proyecto de forma clara, separando el código de la aplicación, la infraestructura y los pipelines. Así es más fácil mantener y colaborar en equipo.

repository/
├── .azure/
│   └── pipelines/
│       ├── ci.yml
│       └── cd.yml
├── terraform/
│   ├── environments/
│   │   ├── dev/
│   │   ├── staging/
│   │   └── prod/
│   ├── modules/
│   │   ├── compute/
│   │   ├── network/
│   │   └── database/
│   └── main.tf
├── kubernetes/
│   ├── base/
│   └── overlays/
└── src/
    └── microservices/

Implementación del Pipeline CI/CD

1. Azure Pipeline Principal

Este archivo YAML define el pipeline de integración continua (CI) en Azure DevOps. Se activa cuando hay cambios en las ramas principales o en archivos específicos, y valida la infraestructura antes de desplegar.

# .azure/pipelines/ci.yml
trigger:
  branches:
    include:
    - main
    - feature/*
  paths:
    include:
    - src/*
    - terraform/*
    - kubernetes/*

variables:
  - group: terraform-secrets
  - name: ENVIRONMENT
    value: 'dev'

stages:
- stage: ValidateInfrastructure
  jobs:
  - job: TerraformValidate
    pool:
      vmImage: 'ubuntu-latest'
    steps:
    - task: TerraformInstaller@0
      inputs:
        terraformVersion: '1.5.7'
    
    - task: TerraformTaskV4@4
      inputs:
        provider: 'azurerm'
        command: 'init'
        workingDirectory: '$(System.DefaultWorkingDirectory)/terraform'
        backendServiceArm: 'terraform-backend'
        backendAzureRmResourceGroupName: 'terraform-storage-rg'
        backendAzureRmStorageAccountName: 'tfstate'
        backendAzureRmContainerName: 'tfstate'
        backendAzureRmKey: '$(ENVIRONMENT).tfstate'

    - task: TerraformTaskV4@4
      inputs:
        provider: 'azurerm'
        command: 'plan'
        workingDirectory: '$(System.DefaultWorkingDirectory)/terraform'
        environmentServiceNameAzureRM: 'terraform-backend'

- stage: BuildAndTest
  jobs:
  - job: BuildCode
    steps:
    - task: DotNetCoreCLI@2
      inputs:
        command: 'build'
        projects: 'src/**/*.csproj'
    
    - task: DotNetCoreCLI@2
      inputs:
        command: 'test'
        projects: 'tests/**/*.csproj'

- stage: SecurityScan
  jobs:
  - job: CodeScan
    steps:
    - task: SonarCloudPrepare@1
      inputs:
        SonarCloud: 'sonarcloud'
        organization: 'your-org'
        scannerMode: 'CLI'
        configMode: 'manual'
        cliProjectKey: 'your-project'
        cliProjectName: 'Your Project'

    - task: SonarCloudAnalyze@1

2. Despliegue con GitOps

Este pipeline de despliegue continuo (CD) se activa después del CI y aplica los cambios a la infraestructura y aplicaciones usando GitOps con Flux.

# .azure/pipelines/cd.yml
trigger: none
pr: none

resources:
  pipelines:
    - pipeline: CI
      source: CI-Pipeline
      trigger: 
        branches:
          include:
          - main

variables:
  - group: gitops-secrets

stages:
- stage: DeployInfrastructure
  jobs:
  - deployment: TerraformApply
    environment: $(ENVIRONMENT)
    strategy:
      runOnce:
        deploy:
          steps:
          - task: TerraformTaskV4@4
            inputs:
              provider: 'azurerm'
              command: 'apply'
              workingDirectory: '$(Pipeline.Workspace)/terraform'
              environmentServiceNameAzureRM: 'terraform-backend'

- stage: DeployApplications
  jobs:
  - deployment: FluxCD
    environment: $(ENVIRONMENT)
    strategy:
      runOnce:
        deploy:
          steps:
          - task: Kubernetes@1
            inputs:
              connectionType: 'Kubernetes Service Connection'
              kubernetesServiceEndpoint: 'aks-connection'
              command: 'apply'
              arguments: '-f $(Pipeline.Workspace)/kubernetes/flux/'

Configuración de GitOps con Flux

1. Flux Bootstrap

Este archivo configura Flux para que monitoree cambios en el repositorio Git y aplique automáticamente las actualizaciones a Kubernetes.

# kubernetes/flux/gotk-components.yaml
apiVersion: source.toolkit.fluxcd.io/v1beta2
kind: GitRepository
metadata:
  name: flux-system
  namespace: flux-system
spec:
  interval: 1m0s
  ref:
    branch: main
  secretRef:
    name: flux-system
  url: ssh://git@github.com/your-org/your-repo.git

---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
  name: flux-system
  namespace: flux-system
spec:
  interval: 10m0s
  path: ./kubernetes/base
  prune: true
  sourceRef:
    kind: GitRepository
    name: flux-system

2. Aplicación Base

# kubernetes/base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - deployment.yaml
  - service.yaml
  - ingress.yaml

commonLabels:
  app: microservice
  environment: base

Seguridad y Cumplimiento

1. Policy as Code

# terraform/policies/main.tf
resource "azurerm_policy_definition" "require_tags" {
  name         = "require-tags"
  policy_type  = "Custom"
  mode         = "Indexed"
  display_name = "Require tags on resources"

  policy_rule = <<POLICY_RULE
{
  "if": {
    "field": "tags",
    "exists": "false"
  },
  "then": {
    "effect": "deny"
  }
}
POLICY_RULE
}

2. Seguridad en Pipeline

# .azure/pipelines/security.yml
trigger: none

schedules:
- cron: "0 0 * * *"
  displayName: Daily Security Scan
  branches:
    include:
    - main
  always: true

pool:
  vmImage: 'ubuntu-latest'

steps:
- task: ContainerStructureTest@0
  inputs:
    dockerFile: '**/Dockerfile'
    testFile: '**/test.yaml'

- task: Checkmarx@1
  inputs:
    projectName: '$(Build.Repository.Name)'
    checkmarxUsername: '$(checkmarx.username)'
    checkmarxPassword: '$(checkmarx.password)'
    checkmarxServerUrl: '$(checkmarx.url)'

Monitorización y Observabilidad

1. Prometheus y Grafana

# kubernetes/monitoring/prometheus.yaml
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
  name: prometheus
spec:
  serviceAccountName: prometheus
  serviceMonitorSelector:
    matchLabels:
      team: frontend
  resources:
    requests:
      memory: 400Mi

2. Logging con Azure Monitor

resource "azurerm_log_analytics_workspace" "main" {
  name                = "workspace-${var.environment}"
  location            = var.location
  resource_group_name = azurerm_resource_group.main.name
  sku                = "PerGB2018"
  retention_in_days   = 30
}

Automatización de Pruebas

1. Pruebas de Infraestructura

# tests/main.tf
module "test" {
  source = "../modules/network"

  providers = {
    azurerm = azurerm.test
  }

  # Test inputs
  vnet_name = "test-vnet"
  address_space = ["10.0.0.0/16"]
}

# Test assertions
resource "test_assertions" "network" {
  component = "network"

  equal "vnet_name" {
    description = "VNet name should match input"
    got         = module.test.vnet_name
    want        = "test-vnet"
  }
}

2. Pruebas de Integración

# tests/integration/test.yaml
apiVersion: v1
kind: Pod
metadata:
  name: integration-test
spec:
  containers:
  - name: test
    image: test-runner:latest
    env:
    - name: API_ENDPOINT
      value: http://api-service
    command: ["pytest", "-v", "tests/"]

Mejores Prácticas

  1. Control de Versiones
    • Ramificación por característica
    • Pull requests obligatorios
    • Revisiones de código automatizadas
  2. Seguridad
    • Escaneo de secretos
    • Análisis de dependencias
    • RBAC granular
  3. Monitorización
    • Métricas de pipeline
    • Logs centralizados
    • Alertas proactivas
  4. Automatización
    • Pruebas automatizadas
    • Despliegues automáticos
    • Rollbacks automáticos

Conclusiones

Un pipeline DevOps moderno requiere:

  1. Automatización completa
  2. Seguridad integrada
  3. Observabilidad robusta
  4. GitOps como base

Próximos Pasos

  1. Implementar control de versiones
  2. Configurar CI/CD básico
  3. Integrar seguridad
  4. Implementar GitOps
  5. Añadir monitorización

Referencias