DevOps: Do Básico ao Avançado Já leu

O que é DevOps e Por Que Importa DevOps é uma cultura que unifica desenvolvimento (Dev) e operações (Ops), quebrando silos organizacionais e promovendo colaboração contínua. O objetivo é acelerar a entrega de software com qualidade, automatizando processos desde o código até a produção. Não é apenas uma ferramenta ou cargo, mas uma mentalidade que valoriza comunicação, automação, medição e compartilhamento (CAMS). Na prática, DevOps resolve problemas clássicos: deploys demorados, ambientes inconsistentes, falta de visibilidade sobre falhas e sobrecarga operacional. Empresas que adotam DevOps reduzem o tempo de lançamento de funcionalidades de semanas para horas, aumentam a taxa de sucesso de deploys e respondem a incidentes mais rapidamente. Princípios Fundamentais Integração e Entrega Contínua (CI/CD): automatizar build, testes e deploy Infraestrutura como Código (IaC): versionar e automatizar infraestrutura Monitoramento e Feedback: observabilidade em tempo real Colaboração: times multifuncionais com responsabilidade compartilhada CI/CD: Automatizando o Pipeline CI/CD é o coração do DevOps. Integração Contínua (CI) automatiza a compilação e testes a

O que é DevOps e Por Que Importa

DevOps é uma cultura que unifica desenvolvimento (Dev) e operações (Ops), quebrando silos organizacionais e promovendo colaboração contínua. O objetivo é acelerar a entrega de software com qualidade, automatizando processos desde o código até a produção. Não é apenas uma ferramenta ou cargo, mas uma mentalidade que valoriza comunicação, automação, medição e compartilhamento (CAMS).

Na prática, DevOps resolve problemas clássicos: deploys demorados, ambientes inconsistentes, falta de visibilidade sobre falhas e sobrecarga operacional. Empresas que adotam DevOps reduzem o tempo de lançamento de funcionalidades de semanas para horas, aumentam a taxa de sucesso de deploys e respondem a incidentes mais rapidamente.

Princípios Fundamentais

  • Integração e Entrega Contínua (CI/CD): automatizar build, testes e deploy
  • Infraestrutura como Código (IaC): versionar e automatizar infraestrutura
  • Monitoramento e Feedback: observabilidade em tempo real
  • Colaboração: times multifuncionais com responsabilidade compartilhada

CI/CD: Automatizando o Pipeline

CI/CD é o coração do DevOps. Integração Contínua (CI) automatiza a compilação e testes a cada commit, detectando bugs cedo. Entrega Contínua (CD) garante que o código esteja sempre pronto para deploy, enquanto Deploy Contínuo automatiza o envio para produção.

Ferramentas populares incluem Jenkins, GitLab CI, GitHub Actions e CircleCI. Vamos criar um pipeline completo com GitHub Actions que testa e faz deploy de uma aplicação Node.js:

# .github/workflows/ci-cd.yml
name: CI/CD Pipeline

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Run tests
        run: npm test

      - name: Run linter
        run: npm run lint

  build-and-deploy:
    needs: test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - uses: actions/checkout@v3

      - name: Build Docker image
        run: docker build -t myapp:${{ github.sha }} .

      - name: Login to Docker Hub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Push image
        run: |
          docker tag myapp:${{ github.sha }} myuser/myapp:latest
          docker push myuser/myapp:latest

      - name: Deploy to production
        run: |
          kubectl set image deployment/myapp \
            myapp=myuser/myapp:latest \
            --record

Este pipeline executa testes em cada push, constrói a imagem Docker apenas na branch principal e faz deploy automático no Kubernetes. A separação em jobs garante que o deploy só ocorra se os testes passarem.

Estratégias de Deploy Avançadas

Blue-Green Deployment: mantém dois ambientes idênticos (blue e green). O tráfego é redirecionado instantaneamente entre eles, permitindo rollback imediato.

Canary Deployment: libera gradualmente para uma pequena porcentagem de usuários antes do rollout completo, reduzindo riscos.

# Exemplo de Canary com Kubernetes e Istio
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: myapp-canary
spec:
  hosts:
  - myapp.example.com
  http:
  - match:
    - headers:
        user-type:
          exact: beta
    route:
    - destination:
        host: myapp
        subset: v2
  - route:
    - destination:
        host: myapp
        subset: v1
      weight: 90
    - destination:
        host: myapp
        subset: v2
      weight: 10

Infraestrutura como Código com Terraform

IaC trata infraestrutura como software versionado, reproduzível e testável. Terraform é a ferramenta líder, usando HCL (HashiCorp Configuration Language) para declarar recursos em múltiplos provedores de nuvem.

Um exemplo real provisionando infraestrutura AWS completa:

# main.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
  backend "s3" {
    bucket = "terraform-state-prod"
    key    = "infrastructure/terraform.tfstate"
    region = "us-east-1"
  }
}

provider "aws" {
  region = var.aws_region
}

# VPC e networking
resource "aws_vpc" "main" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_hostnames = true

  tags = {
    Name        = "production-vpc"
    Environment = "production"
  }
}

resource "aws_subnet" "public" {
  count                   = 2
  vpc_id                  = aws_vpc.main.id
  cidr_block              = "10.0.${count.index + 1}.0/24"
  availability_zone       = data.aws_availability_zones.available.names[count.index]
  map_public_ip_on_launch = true
}

# EKS Cluster
resource "aws_eks_cluster" "main" {
  name     = "production-cluster"
  role_arn = aws_iam_role.eks_cluster.arn
  version  = "1.28"

  vpc_config {
    subnet_ids = aws_subnet.public[*].id
  }

  depends_on = [
    aws_iam_role_policy_attachment.eks_cluster_policy
  ]
}

# Node Group
resource "aws_eks_node_group" "main" {
  cluster_name    = aws_eks_cluster.main.name
  node_group_name = "production-nodes"
  node_role_arn   = aws_iam_role.eks_nodes.arn
  subnet_ids      = aws_subnet.public[*].id

  scaling_config {
    desired_size = 3
    max_size     = 5
    min_size     = 2
  }

  instance_types = ["t3.medium"]
}

# Outputs para usar em outros módulos
output "cluster_endpoint" {
  value = aws_eks_cluster.main.endpoint
}

output "cluster_name" {
  value = aws_eks_cluster.main.name
}

Comandos essenciais do Terraform:

# Inicializar e baixar providers
terraform init

# Planejar mudanças (dry-run)
terraform plan

# Aplicar mudanças
terraform apply

# Destruir recursos
terraform destroy

# Importar recurso existente
terraform import aws_instance.example i-1234567890abcdef0

O uso de módulos reutilizáveis e remote state (S3 backend) permite colaboração eficiente entre times. Sempre versione código IaC no Git e use pull requests com terraform plan nos comentários.

Observabilidade: Monitoramento e Logging

Observabilidade vai além de monitoramento tradicional, combinando métricas, logs e traces distribuídos. O stack mais usado é Prometheus (métricas), Grafana (visualização), Loki (logs) e Jaeger (tracing).

Implementando Métricas com Prometheus

# app.py - Aplicação Flask com métricas Prometheus
from flask import Flask, request
from prometheus_client import Counter, Histogram, generate_latest
import time

app = Flask(__name__)

# Métricas customizadas
REQUEST_COUNT = Counter(
    'http_requests_total',
    'Total de requisições HTTP',
    ['method', 'endpoint', 'status']
)

REQUEST_DURATION = Histogram(
    'http_request_duration_seconds',
    'Duração das requisições HTTP',
    ['method', 'endpoint']
)

@app.before_request
def before_request():
    request.start_time = time.time()

@app.after_request
def after_request(response):
    duration = time.time() - request.start_time
    REQUEST_DURATION.labels(
        method=request.method,
        endpoint=request.path
    ).observe(duration)

    REQUEST_COUNT.labels(
        method=request.method,
        endpoint=request.path,
        status=response.status_code
    ).inc()

    return response

@app.route('/api/users')
def get_users():
    return {'users': ['Alice', 'Bob']}

@app.route('/metrics')
def metrics():
    return generate_latest()

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

Configuração do Prometheus para scraping:

# prometheus.yml
global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: 'flask-app'
    static_configs:
      - targets: ['app:5000']
    metrics_path: '/metrics'

  - job_name: 'kubernetes-pods'
    kubernetes_sd_configs:
      - role: pod
    relabel_configs:
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
        action: keep
        regex: true

Alertas Inteligentes

# alerts.yml - Regras de alerta Prometheus
groups:
  - name: application_alerts
    interval: 30s
    rules:
      - alert: HighErrorRate
        expr: |
          rate(http_requests_total{status=~"5.."}[5m]) 
          / rate(http_requests_total[5m]) > 0.05
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "Taxa de erro alta em {{ $labels.instance }}"
          description: "{{ $value | humanizePercentage }} de erros nos últimos 5 minutos"

      - alert: PodCrashLooping
        expr: rate(kube_pod_container_status_restarts_total[15m]) > 0
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Pod {{ $labels.pod }} reiniciando continuamente"

Conclusão

  • DevOps é cultura antes de tecnologia: CI/CD, IaC e observabilidade são ferramentas que viabilizam colaboração, automação e feedback contínuo entre desenvolvimento e operações
  • Automatize tudo: desde testes unitários até provisionamento de infraestrutura, automação reduz erros humanos e acelera entregas com qualidade consistente
  • Meça para melhorar: observabilidade com métricas, logs e traces permite decisões baseadas em dados reais, identificando gargalos e antecipando problemas antes de impactar usuários

Referências


Artigos relacionados