DevOps

Cultura DevOps: Maturidade, Postmortems e Melhoria Contínua Já leu

20 min de leitura

Cultura DevOps: Maturidade, Postmortems e Melhoria Contínua
É possível instalar todas as ferramentas descritas nos artigos anteriores — Kubernetes, ArgoCD, Prometheus, Falco, Backstage — e ainda assim ter uma organização que entrega software lentamente, sofre incidentes frequente

É possível instalar todas as ferramentas descritas nos artigos anteriores — Kubernetes, ArgoCD, Prometheus, Falco, Backstage — e ainda assim ter uma organização que entrega software lentamente, sofre incidentes frequentes e não aprende com seus erros. As ferramentas são necessárias mas não suficientes. O que determina se uma organização DevOps é de alto desempenho ou medíocre é, em última análise, cultural: como as pessoas colaboram, como respondem a falhas, como tomam decisões e como aprendem.

O relatório State of DevOps, produzido anualmente pelo DORA — DevOps Research and Assessment — é o estudo longitudinal mais abrangente sobre performance em entrega de software. Ao longo de mais de uma década de pesquisa com dezenas de milhares de organizações, o DORA identificou que os maiores preditores de performance organizacional em entrega de software não são as ferramentas usadas, mas práticas culturais: psicologia de segurança para relatar problemas sem medo de punição, trabalho em pequenos lotes, colaboração entre times e foco em aprendizado contínuo.

Este artigo explora como medir a maturidade de uma organização DevOps, como conduzir postmortems que geram aprendizado real em vez de relatórios que são arquivados, e como construir os rituais de melhoria contínua que sustentam a evolução ao longo do tempo.


Medindo Maturidade DevOps com as Métricas DORA

As quatro métricas DORA — introduzidas no Artigo 19 em seu contexto de pipeline — são, em sua forma completa, métricas de resultado organizacional que medem a capacidade de entrega de valor com qualidade:

Deployment Frequency — com que frequência a organização faz deploy em produção. Times de elite fazem múltiplos deploys por dia. Times de baixo desempenho fazem deploys mensais ou menos frequentes.

Lead Time for Changes — tempo desde o commit até o código estar em produção. Times de elite medem em minutos a horas. Times de baixo desempenho medem em semanas a meses.

Change Failure Rate — percentual de deploys que resultam em degradação de serviço ou incidente. Times de elite mantêm abaixo de 5%. Times de baixo desempenho chegam a 46-60%.

Time to Restore Service — tempo para restaurar o serviço após um incidente. Times de elite restauram em menos de uma hora. Times de baixo desempenho levam de uma semana a um mês.

Coletando as Métricas DORA Automaticamente

// scripts/coletar-metricas-dora.js
// Coleta as quatro métricas DORA via GitHub API e dados de incidente
// Executa diariamente via pipeline e publica no Prometheus Pushgateway

const { Octokit } = require('@octokit/rest');
const { Pushgateway, Gauge } = require('prom-client');

const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });
const pushgateway = new Pushgateway(process.env.PROMETHEUS_PUSHGATEWAY);

const ORG = process.env.GITHUB_ORG;
const REPO = process.env.GITHUB_REPO;
const JANELA_DIAS = 30;

// ── Deployment Frequency ─────────────────────────────────────────────

async function calcularDeployFrequency() {
  const fim = new Date();
  const inicio = new Date(fim - JANELA_DIAS * 24 * 60 * 60 * 1000);

  // Busca todos os deployments no período
  const { data: deployments } = await octokit.repos.listDeployments({
    owner: ORG,
    repo: REPO,
    environment: 'production',
    per_page: 100,
  });

  const deploymentsNoPeriodo = deployments.filter(d => {
    const criado = new Date(d.created_at);
    return criado >= inicio && criado <= fim;
  });

  // Conta apenas deployments bem-sucedidos
  const deploymentsSuccessful = await Promise.all(
    deploymentsNoPeriodo.map(async d => {
      const { data: statuses } = await octokit.repos.listDeploymentStatuses({
        owner: ORG,
        repo: REPO,
        deployment_id: d.id,
        per_page: 1,
      });
      return statuses[0]?.state === 'success';
    })
  );

  const totalSuccessful = deploymentsSuccessful.filter(Boolean).length;
  const deploysPerDia = totalSuccessful / JANELA_DIAS;

  return {
    total: totalSuccessful,
    porDia: deploysPerDia,
    classificacao: classificarDeployFrequency(deploysPerDia),
  };
}

function classificarDeployFrequency(deploysPerDia) {
  if (deploysPerDia >= 1)   return 'elite';    // >= 1 deploy/dia
  if (deploysPerDia >= 0.14) return 'alto';    // >= 1/semana
  if (deploysPerDia >= 0.03) return 'medio';   // >= 1/mês
  return 'baixo';
}

// ── Lead Time for Changes ─────────────────────────────────────────────

async function calcularLeadTime() {
  const fim = new Date();
  const inicio = new Date(fim - JANELA_DIAS * 24 * 60 * 60 * 1000);

  // Busca PRs mergeados no período
  const { data: pulls } = await octokit.pulls.list({
    owner: ORG,
    repo: REPO,
    state: 'closed',
    base: 'main',
    per_page: 100,
    sort: 'updated',
    direction: 'desc',
  });

  const prsMergeados = pulls.filter(pr => {
    if (!pr.merged_at) return false;
    const mergedAt = new Date(pr.merged_at);
    return mergedAt >= inicio && mergedAt <= fim;
  });

  if (prsMergeados.length === 0) {
    return { mediaMinutos: null, classificacao: 'sem-dados' };
  }

  // Calcula o tempo desde o primeiro commit até o merge
  const leadTimes = await Promise.all(
    prsMergeados.map(async pr => {
      const { data: commits } = await octokit.pulls.listCommits({
        owner: ORG,
        repo: REPO,
        pull_number: pr.number,
        per_page: 1,
      });

      // Usa a data do primeiro commit como início do lead time
      const primeiroCommit = commits[commits.length - 1];
      if (!primeiroCommit) return null;

      const inicio = new Date(primeiroCommit.commit.author.date);
      const fim = new Date(pr.merged_at);
      return (fim - inicio) / (1000 * 60); // Converte para minutos
    })
  );

  const leadTimesValidos = leadTimes.filter(Boolean);
  const media = leadTimesValidos.reduce((a, b) => a + b, 0) / leadTimesValidos.length;

  return {
    mediaMinutos: Math.round(media),
    mediaHoras: Math.round(media / 60),
    classificacao: classificarLeadTime(media),
  };
}

function classificarLeadTime(minutos) {
  const horas = minutos / 60;
  if (horas <= 24)      return 'elite';   // < 1 dia
  if (horas <= 168)     return 'alto';    // < 1 semana
  if (horas <= 720)     return 'medio';   // < 1 mês
  return 'baixo';
}

// ── Change Failure Rate ───────────────────────────────────────────────

async function calcularChangeFailureRate() {
  const fim = new Date();
  const inicio = new Date(fim - JANELA_DIAS * 24 * 60 * 60 * 1000);

  // Busca deployments totais
  const { data: deployments } = await octokit.repos.listDeployments({
    owner: ORG,
    repo: REPO,
    environment: 'production',
    per_page: 100,
  });

  const deploymentsNoPeriodo = deployments.filter(d =>
    new Date(d.created_at) >= inicio
  );

  // Busca incidentes do período via PagerDuty API
  const incidentesResponse = await fetch(
    `https://api.pagerduty.com/incidents?` +
    `since=${inicio.toISOString()}&until=${fim.toISOString()}&` +
    `service_ids[]=${process.env.PAGERDUTY_SERVICE_ID}`,
    {
      headers: {
        Authorization: `Token token=${process.env.PAGERDUTY_TOKEN}`,
        Accept: 'application/vnd.pagerduty+json;version=2',
      },
    }
  );

  const { incidents } = await incidentesResponse.json();

  // Incidentes causados por deploy (tem tag "deploy-related")
  const incidentesDeployRelated = incidents.filter(i =>
    i.tags?.some(t => t.label === 'deploy-related')
  );

  const cfr = deploymentsNoPeriodo.length > 0
    ? (incidentesDeployRelated.length / deploymentsNoPeriodo.length) * 100
    : 0;

  return {
    totalDeploys: deploymentsNoPeriodo.length,
    totalIncidentes: incidentesDeployRelated.length,
    percentual: Math.round(cfr * 10) / 10,
    classificacao: classificarCFR(cfr),
  };
}

function classificarCFR(percentual) {
  if (percentual <= 5)  return 'elite';
  if (percentual <= 15) return 'alto';
  if (percentual <= 45) return 'medio';
  return 'baixo';
}

// ── Publica métricas no Prometheus ───────────────────────────────────

async function publicarMetricas() {
  const [deployFreq, leadTime, cfr] = await Promise.all([
    calcularDeployFrequency(),
    calcularLeadTime(),
    calcularChangeFailureRate(),
  ]);

  const metricaDeployFreq = new Gauge({
    name: 'dora_deployment_frequency_daily',
    help: 'Número médio de deploys por dia nos últimos 30 dias',
    labelNames: ['repositorio', 'classificacao'],
  });

  const metricaLeadTime = new Gauge({
    name: 'dora_lead_time_minutes',
    help: 'Lead time médio em minutos nos últimos 30 dias',
    labelNames: ['repositorio', 'classificacao'],
  });

  const metricaCFR = new Gauge({
    name: 'dora_change_failure_rate_percent',
    help: 'Taxa de falha de mudanças em percentual nos últimos 30 dias',
    labelNames: ['repositorio', 'classificacao'],
  });

  metricaDeployFreq.set(
    { repositorio: REPO, classificacao: deployFreq.classificacao },
    deployFreq.porDia
  );

  if (leadTime.mediaMinutos) {
    metricaLeadTime.set(
      { repositorio: REPO, classificacao: leadTime.classificacao },
      leadTime.mediaMinutos
    );
  }

  metricaCFR.set(
    { repositorio: REPO, classificacao: cfr.classificacao },
    cfr.percentual
  );

  await pushgateway.pushAdd({
    jobName: 'dora-metrics',
    groupings: { repositorio: REPO },
  });

  console.log(JSON.stringify({
    level: 'info',
    msg: 'Métricas DORA publicadas',
    deployFrequency: deployFreq,
    leadTime,
    changeFailureRate: cfr,
  }, null, 2));
}

publicarMetricas().catch(console.error);

Postmortems Sem Culpa: Aprendendo com Incidentes

O postmortem — também chamado de incident review ou after-action review — é o processo estruturado de analisar um incidente após sua resolução para extrair aprendizados e definir ações que evitem recorrência. A qualidade cultural de uma organização se revela mais claramente em como ela conduz seus postmortems do que em quase qualquer outra prática.

A Cultura de Não-Culpa

O princípio da culpa zero — blameless postmortem — parte de uma premissa fundamentada em décadas de pesquisa em segurança industrial: em sistemas complexos, incidentes são quase sempre o resultado de múltiplos fatores que se combinaram de maneira imprevista, não da incompetência ou negligência de um indivíduo.

Quando uma organização trata incidentes como oportunidades para encontrar e punir culpados, produz três efeitos destrutivos: as pessoas deixam de reportar problemas por medo de punição; os postmortems se tornam exercícios defensivos em vez de investigativos; e as causas sistêmicas dos incidentes permanecem intocadas enquanto o indivíduo "culpado" é removido ou punido.

A cultura de não-culpa não significa ausência de responsabilidade — significa que a responsabilidade é coletiva e sistêmica. O engenheiro que fez o deploy que causou o incidente não é culpado; o sistema que permitiu aquele deploy sem os controles adequados é o problema a ser corrigido.

Estrutura de um Postmortem Eficaz

# Postmortem: Indisponibilidade do Serviço de Checkout
**Data do incidente:** 2025-03-10
**Duração:** 47 minutos (14h23 — 15h10 UTC)
**Severidade:** SEV-1
**Facilitador:** Ana Costa
**Participantes:** Pedro Silva, Luiza Mendes, Carlos Santos, Maria Lima

---

## Sumário Executivo

Indisponibilidade completa do serviço de checkout durante 47 minutos,
afetando aproximadamente 2.300 usuários. Causa raiz: migration de banco
de dados que adicionou índice em tabela de pedidos (23M linhas) sem
usar criação concorrente, bloqueando todas as escritas durante a
construção do índice. Estimativa de impacto: R$ 87.000 em pedidos não
concluídos no período.

---

## Linha do Tempo

| Hora (UTC) | Evento                                                                 |
|------------|------------------------------------------------------------------------|
| 14:18      | Deploy v2.4.1 iniciado via pipeline de CI/CD                          |
| 14:23      | Migration executada — início da construção do índice em produção      |
| 14:24      | Primeiros alertas de timeout no Grafana (latência p99 > 5s)           |
| 14:26      | PagerDuty aciona plantão — Pedro Silva                                 |
| 14:31      | Pedro identifica a migration como causa provável via Performance Insights |
| 14:35      | Decisão de rollback discutida — migration não é facilmente reversível  |
| 14:40      | Opção escolhida: cancelar a construção do índice via pg_cancel_backend |
| 14:52      | Índice cancelado — serviço começa a se recuperar                      |
| 15:10      | Todos os pods saudáveis, métricas normalizadas                         |
| 15:15      | Incidente declarado resolvido                                          |
| 15:45      | Comunicação enviada para clientes afetados                             |

---

## Causa Raiz

A migration `20250310_add_index_pedidos_usuario_id.sql` criou um índice
usando o comando padrão `CREATE INDEX`, que adquire um `AccessShareLock`
na tabela durante toda a construção. Para tabelas de 23M linhas, a
construção levou aproximadamente 29 minutos — bloqueando todas as
operações de escrita durante esse período.

O comando correto para tabelas em produção é
`CREATE INDEX CONCURRENTLY`, que constrói o índice em segundo plano
sem bloquear escritas, mas requer atenção especial (não pode ser
executado dentro de uma transaction block).

---

## Fatores Contribuintes

**Fatores técnicos:**
- Não havia validação automatizada de migrations contra tabelas grandes
  antes do deploy
- O ambiente de staging tem apenas ~50K linhas na tabela de pedidos,
  tornando o impacto invisível em testes
- Não havia alerta configurado para `lock_waits` prolongados no RDS

**Fatores de processo:**
- A revisão do PR não incluiu avaliação do impacto da migration em
  produção (revisores focaram no código da aplicação)
- Não havia um checklist de pre-deploy para migrations em tabelas grandes
- O runbook de rollback de migrations não estava atualizado

**Fatores de conhecimento:**
- A diferença entre CREATE INDEX e CREATE INDEX CONCURRENTLY
  não estava documentada nas diretrizes de migrations
- Novos membros do time não recebem treinamento específico sobre
  operações seguras em banco de dados de produção

---

## O Que Funcionou Bem

- O alerta de latência p99 disparou 2 minutos após o início do incidente —
  tempo de detecção excelente
- Pedro identificou a causa raiz em menos de 10 minutos usando
  Performance Insights e CloudWatch Logs
- A comunicação interna via Slack foi clara e frequente durante o incidente
- O time tomou a decisão correta de cancelar o índice em vez de esperar,
  evitando uma hora adicional de indisponibilidade

---

## Ações Corretivas

| Ação | Responsável | Prazo | Issue |
|------|-------------|-------|-------|
| Adicionar lint de migrations que detecta CREATE INDEX sem CONCURRENTLY em tabelas > 1M linhas | Pedro Silva | 2025-03-17 | #1847 |
| Atualizar o ambiente de staging para ter volume de dados proporcional ao de produção (sample de 10%) | Luiza Mendes | 2025-03-24 | #1848 |
| Criar checklist de pre-deploy para migrations com verificação de tamanho de tabela | Ana Costa | 2025-03-14 | #1849 |
| Adicionar alerta de lock_wait_timeout prolongado no CloudWatch | Carlos Santos | 2025-03-17 | #1850 |
| Documentar migrations seguras em tabelas grandes no wiki de engenharia | Maria Lima | 2025-03-21 | #1851 |
| Incluir módulo de banco de dados em produção no onboarding de novos engenheiros | Ana Costa | 2025-03-28 | #1852 |

---

## Métricas do Incidente

- **MTTD** (Mean Time to Detect): 3 minutos
- **MTTI** (Mean Time to Identify): 8 minutos  
- **MTTR** (Mean Time to Restore): 47 minutos
- **Usuários afetados:** ~2.300
- **Impacto estimado:** R$ 87.000

---

## Aprendizados para o Time

Esta não é a primeira vez que uma migration de banco de dados causa
incidente — em agosto de 2024 tivemos um incidente similar por um
ALTER TABLE sem DEFAULT em tabela grande. O padrão indica uma lacuna
sistêmica em nosso processo de validação de migrations, não um
problema de competência individual.

A ação de maior impacto não é o lint (que é preventivo), mas a
paridade de dados entre staging e produção — sem ela, nenhuma
quantidade de revisão manual detectará problemas de escala.

Facilitando um Postmortem Eficaz

O facilitador do postmortem tem a responsabilidade de criar um ambiente onde as pessoas sintam segurança para compartilhar o que realmente aconteceu:

## Guia do Facilitador de Postmortem

### Antes da reunião
- [ ] Leia todos os logs e alertas do período do incidente
- [ ] Construa um rascunho da linha do tempo para validar com participantes
- [ ] Identifique as perguntas que ainda precisam de resposta
- [ ] Confirme que todos os participantes relevantes estão convidados
- [ ] Reserve 60–90 minutos (incidentes complexos podem precisar de mais)

### Durante a reunião

**Abertura (5 min)**
Reforce explicitamente que o objetivo é aprender, não atribuir culpa.
Exemplo de fala: "Estamos aqui para entender o que aconteceu e o que
podemos melhorar como sistema e como time. Não há respostas erradas,
e ninguém será julgado pelas decisões que tomou com as informações
que tinha no momento."

**Revisão da linha do tempo (15–20 min)**
Percorra a linha do tempo cronologicamente. Para cada evento, pergunte:
- O que você estava vendo nesse momento?
- Qual informação você tinha disponível?
- O que você considerou antes de tomar essa decisão?

**Análise de causa raiz (20–30 min)**
Use os "5 Porquês" iterativamente até chegar a causas sistêmicas.
Evite parar no primeiro "erro humano" — pergunte: "O que no sistema
tornou esse erro possível?"

Exemplo:
- Por que o serviço ficou indisponível? → Migration bloqueou escritas
- Por que a migration bloqueou escritas? → CREATE INDEX sem CONCURRENTLY
- Por que foi usado CREATE INDEX sem CONCURRENTLY? → Desenvolvedor
  não conhecia a diferença
- Por que o desenvolvedor não conhecia? → Não há documentação nem
  treinamento específico sobre isso
- Por que não há documentação? → Nunca foi priorizado formalmente
→ Causa sistêmica: lacuna de conhecimento não documentada

**Definição de ações (15–20 min)**
Para cada causa sistêmica, defina uma ação com responsável e prazo.
Prefira ações preventivas (detecção automática) sobre ações paliativas
(treinamento manual). Não defina mais de 5–7 ações — priorize as de
maior impacto.

**Encerramento (5 min)**
Agradeça a participação de todos. Reforce que o postmortem será
publicado internamente para que toda a organização possa aprender.

### Após a reunião
- [ ] Publique o postmortem no wiki de engenharia em até 48 horas
- [ ] Crie os issues/tickets para todas as ações definidas
- [ ] Agende revisão de 30 dias para verificar o progresso das ações
- [ ] Atualize o dashboard de incidentes com os dados do postmortem

Rituais de Melhoria Contínua

Os postmortems tratam de incidentes específicos. A melhoria contínua requer rituais que operem em cadências diferentes — diária, semanal, mensal, trimestral:

Retrospectiva Semanal do Time

## Formato de Retrospectiva (60 minutos, sexta-feira)

### Check-in (5 min)
Cada pessoa compartilha uma palavra sobre como está chegando à retro.

### Revisão da semana (10 min)
- Deploys realizados: X
- Incidentes: X (severidade Y)
- Métricas DORA da semana

### O que foi bem (15 min)
Cada pessoa nomeia uma coisa que funcionou bem.
Time vota nas 3 mais importantes para celebrar/manter.

### O que pode melhorar (15 min)
Cada pessoa nomeia uma coisa que foi difícil ou ineficiente.
Time vota nas 3 mais importantes para abordar.

### Ações (10 min)
Para cada item da lista "melhorar", define uma ação com responsável.
Máximo de 3 ações por semana — foco é melhor que quantidade.

### Revisão das ações anteriores (5 min)
Verifica o progresso das ações definidas na retro anterior.

Quarterly Business Review de Engenharia

Uma vez por trimestre, o time de engenharia revisa suas métricas de desempenho em um nível mais alto:

## Engineering QBR — Q1 2025

### Métricas DORA — Evolução Trimestral

| Métrica               | Q4 2024  | Q1 2025  | Δ       | Meta Q2   |
|-----------------------|----------|----------|---------|-----------|
| Deploy Frequency      | 2.1/dia  | 3.8/dia  | +81%    | 5.0/dia   |
| Lead Time             | 4.2h     | 2.1h     | -50%    | < 1h      |
| Change Failure Rate   | 8.3%     | 4.1%     | -51%    | < 3%      |
| MTTR                  | 42min    | 18min    | -57%    | < 15min   |

### Análise de Incidentes SEV-1 e SEV-2

Total de incidentes: 12 (vs 18 em Q4 2024 — redução de 33%)

Causas raiz recorrentes:
- Migrations de banco de dados: 4 incidentes (33%)
- Dependências externas (pagamento, email): 3 incidentes (25%)
- Configuração incorreta de feature flags: 2 incidentes (17%)
- Outros: 3 incidentes (25%)

### Toil Report

Trabalho repetitivo identificado e seu status:
- Rotação manual de credenciais: ELIMINADO (External Secrets Operator)
- Provisioning manual de ambientes: REDUZIDO 70% (Backstage templates)
- Debugging de builds falhando: EM PROGRESSO (melhores mensagens de erro)

### Investimentos para Q2

Baseado na análise acima, os três maiores investimentos para Q2:
1. Lint automático de migrations (4 incidentes prevenidos/trimestre estimado)
2. Chaos Engineering game days mensais (medir resiliência proativamente)
3. Melhorar paridade staging/produção (reduzir surpresas em deploy)

Psicologia de Segurança: A Base de Tudo

O modelo de Westrum — desenvolvido pelo sociólogo Ron Westrum para estudar culturas organizacionais em ambientes de alta complexidade como aviação e medicina — classifica organizações em três tipos:

Patológica — informação é ocultada por medo. Mensageiros são punidos. Falhas são escondidas. Novidades são disruptivas e ameaçadoras.

Burocrática — informação é compartimentada. Responsabilidades são rigidamente definidas. Processos são seguidos mesmo quando não fazem sentido.

Generativa — informação flui livremente. Responsabilidades são compartilhadas. Falhas são oportunidades de aprendizado. A missão importa mais do que o território.

O DORA demonstrou empiricamente que organizações com cultura generativa têm desempenho significativamente superior em todas as métricas de entrega de software. A cultura generativa não é um fim em si mesmo — é um pré-requisito para que todas as práticas técnicas descritos nesta série funcionem.

Um sinal concreto e mensurável de psicologia de segurança é a disposição dos engenheiros de reportar problemas antes que se tornem incidentes. Organizações que punem os portadores de más notícias rapidamente aprendem a não receber más notícias — até que se tornem incidentes de grandes proporções.


Encerrando o Módulo 9

Com este artigo encerra-se o Módulo 9 — Segurança e Compliance em DevOps — e com ele o conteúdo central do curso. Foram cobertos DevSecOps com integração de segurança em todo o pipeline, compliance e auditoria com geração automatizada de evidências, otimização de performance e custos com FinOps, resiliência com Chaos Engineering, Platform Engineering com Backstage e, neste artigo, a dimensão cultural que torna sustentáveis todas as práticas técnicas.

Os próximos artigos formam o projeto capstone da série — a integração de todos os conceitos em um sistema completo de produção.


Referências para Aprofundamento

Pesquisa e métricas - DORA State of DevOps Report — dora.dev — Relatório anual do DORA com os dados mais recentes sobre performance em entrega de software, incluindo análise das quatro métricas e dos preditores culturais de alto desempenho. - DORA Quick Check — dora.dev — Ferramenta online para avaliar rapidamente o desempenho da organização nas quatro métricas DORA e identificar áreas de melhoria.

Cultura e postmortems - Blameless Postmortems — etsy.com — Artigo original da Etsy que popularizou o conceito de postmortem sem culpa, com a fundamentação filosófica e prática do modelo. - The DevOps Handbook — itrevolution.com — Livro de referência de Gene Kim e colaboradores cobrindo os três caminhos do DevOps — fluxo, feedback e aprendizado contínuo — com casos de estudo de transformações reais. - An Elegant Puzzle — Will Larson — lethain.com — Livro sobre gestão de engenharia com capítulos específicos sobre como construir times de alta performance, gestão de incidentes e crescimento organizacional.

Comentários

Mais em DevOps

Variáveis de Ambiente e Secrets em Pipelines
Variáveis de Ambiente e Secrets em Pipelines

Em abril de 2022, a empresa de segurança GitGuardian publicou um relatório re...

GitHub Actions: Sua Primeira Automação de CI/CD
GitHub Actions: Sua Primeira Automação de CI/CD

At&eacute; aqui o reposit&oacute;rio Git funcionou como um arquivo hist&oacut...

Artigo 28 — State do Terraform: Entendendo o Arquivo Mais Crítico do Projeto
Artigo 28 — State do Terraform: Entendendo o Arquivo Mais Crítico do Projeto

Artigo 28 — State do Terraform: Entendendo o Arquivo Mais Crítico do Projeto...