Saltar al contenido
Apside

DevOpsPipelineAutomatizaciónInfraestruturaCloud

[DevOps] Ideas de pipelines para la automatización

Isaias Zelaya ·

Imagen de un archivo .yml con la definición de un pipeline.

Compartiendo parte de la experiencia trabajando con pipelines para la automatización de tareas en el ámbito de DevOps. En términos simples y resumidos, un pipeline puede definirse como una secuencia automatizada de pasos diseñada para construir, probar y desplegar código de manera eficiente y confiable.

Si bien desplegar el código es una parte útil para los que se utiliza un pipeline en este articulo nos enfocaremos en los pipelines para construir procesos que permitan automatizar tareas en el ciclo de vida del desarrollo de software.

A continuación unos ejemplos:

Un pipeline para ahorrar tiempo — Crear infraestructura en la nube

Crear la infraestructura para una aplicación que se comporta de manera inicial de forma similar a otras aplicaciones ya desplegadas puede automatizarse utilizando infraestructura como código con algunas herramientas como Terraform, AWS CloudFormation o Ansible, esto permite entre muchas otras cosas definir las bases de datos, redes y servidores que se necesitan en un archivo de texto.

Previo al despliegue de la infraestructura es posible crear un pipeline para validar y probar las configuraciones antes de aplicarlas en entornos reales. Por ejemplo, los pasos pueden incluir la validación del código de infraestructura, pruebas unitarias y escaneos de seguridad. Esto reduce significativamente el riesgo de errores o configuraciones incorrectas que podrían causar interrupciones en el sistema. Una vez validado, el pipeline ejecuta comandos para aprovisionar o actualizar los recursos de manera controlada y escalable, garantizando que los cambios sean seguros y predecibles.

name: Terraform Infrastructure Pipeline

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  validate-infra:
    runs-on: ubuntu-latest

    steps:
      # Checkout the code
      - name: Checkout Code
        uses: actions/checkout@v3

      # Set up Terraform CLI
      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v2
        with:
          terraform_version: 1.5.0

      # Initialize Terraform
      - name: Terraform Init
        run: terraform init

      # Validate Terraform Configuration
      - name: Terraform Validate
        run: terraform validate

      # Format Terraform Files
      - name: Terraform Format
        run: terraform fmt -check

      # Plan Terraform Changes
      - name: Terraform Plan
        run: terraform plan

      # Optional: Apply Terraform Changes
      - name: Terraform Apply
        if: github.event_name == 'push'
        run: terraform apply -auto-approve

Un pipeline para ahorrar costos — Activar o desactivar ambientes bajos

La optimización de costos es una prioridad constante para las organizaciones, especialmente cuando se trata de utilizar recursos en la nube. En el ciclo de desarrollo de software, es común que los equipos de desarrollo no tengan acceso directo a la administración de la infraestructura en entornos de desarrollo y pruebas. Un ejemplo práctico podría ser la necesidad de un desarrollador de apagar una instancia de AWS EC2 cuando no se requiere, ya sea durante periodos de desarrollo local, en fases donde no se trabajan componentes específicos de un módulo, o en situaciones donde solo el desarrollador conoce cuándo la instancia es innecesaria.

Una solución efectiva es crear un pipeline que incluya los permisos y pasos necesarios para gestionar la instancia, permitiendo que el desarrollador pueda encenderla o apagarla de manera autónoma a través del pipeline. Aunque este ejemplo se centra en un único servidor, el mismo enfoque puede escalarse para abarcar todos los recursos de infraestructura asociados a un módulo o aplicación. El impacto en costos puede ser significativo, especialmente cuando se manejan múltiples aplicaciones y entornos que requieren gestión temporal de recursos.

name: Manage EC2 Instance

on:
  workflow_dispatch:
    inputs:
      action:
        description: "Choose 'start' to power on or 'stop' to power off the instance"
        required: true
        default: "stop"
        type: choice
        options:
          - start
          - stop

jobs:
  manage-ec2:
    runs-on: ubuntu-latest

    steps:
      # Checkout the repository
      - name: Checkout Code
        uses: actions/checkout@v3

      # Configure AWS Credentials
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v3
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: us-east-1

      # Start or Stop EC2 Instance
      - name: Manage EC2 Instance
        run: |
          INSTANCE_ID="i-0123456789abcdef0"
          ACTION=${{ github.event.inputs.action }}
          if [ "$ACTION" == "start" ]; then
            echo "Starting EC2 instance $INSTANCE_ID..."
            aws ec2 start-instances --instance-ids $INSTANCE_ID
          elif [ "$ACTION" == "stop" ]; then
            echo "Stopping EC2 instance $INSTANCE_ID..."
            aws ec2 stop-instances --instance-ids $INSTANCE_ID
          else
            echo "Invalid action: $ACTION"
            exit 1
          fi

Un pipeline para asegurar calidad — Revisar el código fuente previo a un despliegue.

Existen algunas herramientas ejemplo SonarQube que permiten identificar problemas mientras se realiza el desarrollo de software. Una herramienta clave para asegurar la calidad del código fuente puede ser un pipeline que únicamente realice el despliegue de la aplicación de manera automatizada solo si se cumplen todos los estándares de calidad de revisión de código y en caso contrario que proporcione al usuario un resumen detallado de los hallazgos con la herramienta de calidad.

name: Code Review with SonarQube

on:
  pull_request:
    branches:
      - main
  push:
    branches:
      - main

jobs:
  code-review:
    runs-on: ubuntu-latest

    steps:
      # Checkout the code
      - name: Checkout Code
        uses: actions/checkout@v3

      # Set up Python environment
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.9'

      # Install dependencies
      - name: Install Dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt

      # Set up SonarQube Scanner
      - name: Set up SonarQube Scanner
        run: |
          curl -o sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.8.0.2856-linux.zip
          unzip sonar-scanner.zip -d $HOME/
          export PATH="$HOME/sonar-scanner-4.8.0.2856-linux/bin:$PATH"

      # Run SonarQube Analysis
      - name: Run SonarQube
        env:
          SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
        run: |
          sonar-scanner \
            -Dsonar.projectKey=python-flask-app \
            -Dsonar.sources=. \
            -Dsonar.python.version=3.9 \
            -Dsonar.exclusions=**/tests/**

      # Optional: Fail pipeline on quality gate
      - name: Quality Gate Check
        run: |
          if [ $(curl -s -u ${{ secrets.SONAR_TOKEN }}: "${{ secrets.SONAR_HOST_URL }}/api/qualitygates/project_status?projectKey=python-flask-app" | jq -r '.projectStatus.status') != "OK" ]; then
            echo "SonarQube Quality Gate failed. Exiting..."
            exit 1
          fi

  deploy:
    needs: code-review
    runs-on: ubuntu-latest

    steps:
      # Deploy application (example placeholder)
      - name: Deploy Application
        run: echo "Deploying application..."

Un pipeline para asegurar consistencia — Iniciar un repositorio de código fuente

Cuando las empresas adoptan el desarrollo de software basado en microservicios, la gestión de repositorios de código fuente puede convertirse en una tarea laboriosa y con alta carga de trabajo. Un ejemplo práctico de este desafío es cuando los equipos de desarrollo necesitan iniciar un nuevo repositorio y configurar la infraestructura necesaria para comenzar el desarrollo. Este proceso, al depender del equipo de infraestructura, puede generar retrasos significativos.

Si ya se ha definido la tecnología de despliegue, es posible implementar un pipeline automatizado que se conecte a la API del servicio de repositorios de código fuente. Mediante parámetros específicos, este pipeline puede crear el repositorio con configuraciones estándar, como restricciones en las ramas y asignación de accesos.

Esta solución no solo garantiza consistencia en la configuración de los repositorios, sino que también reduce los tiempos de espera, permitiendo a los equipos de desarrollo iniciar el trabajo en sus aplicaciones de manera más ágil y eficiente.

name: Initialize Python Flask Repository

on:
  workflow_dispatch:

jobs:
  initialize-repo:
    runs-on: ubuntu-latest

    steps:
      # Paso 1: Seed
      - name: Checkout Seed Repository
        uses: actions/checkout@v3
        with:
          repository: your-org/your-flask-seed-repo
          token: ${{ secrets.GITHUB_TOKEN }}
          ref: main

      # Paso 2: Clone repository
      - name: Clone New Repository
        run: |
          git clone https://github.com/${{ github.repository }} new-repo
          cd new-repo

      # Paso 3: Copy files
      - name: Copy Flask Seed Files
        run: |
          cp -r * ../new-repo/

      # Paso 4: Installl dependencies
      - name: Install Dependencies
        run: |
          cd ../new-repo
          python -m venv venv
          source venv/bin/activate
          pip install -r requirements.txt

      # Paso 5: Create repository
      - name: Create Initial Commit
        run: |
          cd ../new-repo
          git config --global user.email "youremail@example.com"
          git config --global user.name "GitHub Actions"
          git add .
          git commit -m "Initial commit with Flask seed"
          git push origin main

      # Paso 6: Permissions (si es necesario)
      - name: Set Repository Permissions
        run: |
          curl -u "username:${{ secrets.GITHUB_TOKEN }}" -X PUT \
            -d '{"permission":"push"}' \
            "https://api.github.com/repos/${{ github.repository }}/collaborators/developer-username"
          
      # Paso 7: Notification (opcional)
      - name: Send Notification (Optional)
        run: |
          echo "Repository has been initialized successfully!"

Espero que estos ejemplos de pipelines sirvan como inspiración para generar más casos de uso en la automatización de tareas dentro del ciclo de vida del desarrollo de software.

Seguí leyendo