Modelar um fluxo de trabalho complexo com estágios paralelos e dependências entre os estágios.
→Use pipelines YAML multi-estágios. Use a palavra-chave `dependsOn` para dependências de estágio e configure jobs paralelos dentro dos estágios.
Por quê: YAML oferece a abordagem mais flexível e baseada em código para orquestração complexa, superior aos pipelines clássicos ou ao encadeamento de pipelines separados.
Implementar implantação sem tempo de inatividade e de baixo risco para um aplicativo web com capacidade de rollback instantâneo.
→Use os slots de implantação do Azure App Service. Implante em um slot de preparação (verde), valide e, em seguida, realize uma troca de slot com a produção (azul).
Por quê: Uma troca de slot é uma operação atômica e quase instantânea que redireciona o tráfego. O rollback é tão simples quanto trocar de volta.
Referência↗
Minimizar a duplicação de pipelines para inúmeros microsserviços que compartilham etapas comuns de build/implantação, mas exigem personalizações específicas.
→Crie modelos YAML em um repositório central. Em cada pipeline específico do serviço, use a palavra-chave `extends` e passe parâmetros para personalização.
Por quê: `extends` promove os princípios DRY e impõe padrões, ao mesmo tempo em que permite flexibilidade através de parâmetros. Mais poderoso do que grupos de tarefas para estruturas de pipeline inteiras.
Restringir um estágio de pipeline (por exemplo, implantação em produção) para ser executado apenas em mesclagens para um branch específico (por exemplo, main).
→Use uma `condition` no estágio ou job. Por exemplo, `condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))`.
Por quê: Os builds de validação de PR usam uma referência de branch de origem diferente (por exemplo, `refs/pull/...`), então esta condição impede corretamente a implantação durante o ciclo de vida da PR.
Implantar aplicativos do Azure DevOps em servidores on-premises atrás de um firewall corporativo.
→Instale agentes self-hosted nos servidores on-premises. Registre-os em um pool de agentes no Azure DevOps.
Por quê: Agentes self-hosted iniciam comunicação de saída com o Azure DevOps, portanto, não são necessárias regras de firewall de entrada. Eles podem acessar recursos de rede local para implantação.
Exigir aprovação de várias pessoas para implantações em produção e restringi-las a janelas de manutenção específicas.
→Defina um Ambiente do Azure DevOps para produção. Configure aprovações com aprovadores necessários. Adicione uma verificação de "Horário Comercial" como um "gate" para impor a janela de tempo.
Por quê: Ambientes centralizam os controles de implantação. Aprovações e "gates" fornecem aplicação de políticas robusta e automatizada antes que um estágio seja executado.
Controlar a exposição de recursos aos usuários sem reimplantar o aplicativo, com atualizações em tempo quase real.
→Use o Azure App Configuration para gerenciamento de recursos. Instrumente o aplicativo para ler "flags" e habilite suas capacidades de atualização dinâmica.
Por quê: Desacopla os lançamentos de recursos das implantações. O App Configuration fornece uma UI centralizada e SDKs para atualizações dinâmicas, evitando reinícios do aplicativo.
Gerenciar o estado do cluster Kubernetes de forma declarativa, onde o Git é a única fonte da verdade e as alterações são aplicadas automaticamente.
→Implante um agente GitOps como Flux ou ArgoCD no cluster AKS. Configure o agente para monitorar um repositório Git contendo manifestos Kubernetes e sincronizar automaticamente o estado do cluster.
Por quê: Este modelo baseado em "pull" permite reconciliação contínua e detecção de desvios, que é essencial para GitOps. É mais robusto do que os pipelines `kubectl` baseados em "push".
Gerenciar o estado do Terraform para colaboração em equipe, garantindo segurança e prevenindo modificações concorrentes.
→Configure o backend do Terraform para usar uma Azure Storage Account. Isso fornece armazenamento de estado remoto, com o bloqueio de estado tratado via "lease" de Azure Blob.
Por quê: Evita a corrupção do arquivo de estado por operações `apply` simultâneas e mantém dados de estado sensíveis fora do controle de código-fonte.
Referência↗
Em um monorepo, acionar o pipeline CI de um aplicativo somente quando arquivos em seu diretório específico (ou um diretório compartilhado) forem alterados.
→No YAML do pipeline, use o filtro `trigger.paths.include` para especificar os diretórios relevantes, por exemplo, `include: ['/apps/frontend/**', '/apps/shared/**']`.
Por quê: Isso evita builds desnecessários para alterações de código não relacionadas, economizando tempo de CI e recursos de computação.
Otimizar um estágio de teste com testes rápidos (unitários) e lentos (de integração) para um feedback mais rápido.
→Execute testes unitários e testes de integração em jobs paralelos dentro do mesmo estágio.
Por quê: A execução paralela fornece resultados de testes unitários muito mais rapidamente enquanto testes mais lentos são executados simultaneamente. A duração total do estágio é determinada pelo job mais longo, não pela soma.
Versionar automaticamente um pacote de biblioteca com base no histórico de commits para comunicar claramente o impacto das alterações (quebra, recurso, correção).
→Integre uma ferramenta como GitVersion ao pipeline de CI. Ela analisa mensagens de commit, branches e tags para calcular automaticamente uma versão SemVer (Major.Minor.Patch).
Por quê: SemVer fornece versionamento significativo em que os consumidores podem confiar para gerenciamento de dependências, ao contrário de números de build ou hashes de commit.
Implantar um aplicativo em várias regiões geográficas, uma a uma, com validação após cada implantação regional.
→Use um pipeline YAML multi-estágios com estágios sequenciais, um para cada região, usando `dependsOn` para impor a ordem. Use "environment gates" entre os estágios para validação.
Por quê: Este modelo de implantação baseado em anel contém o raio de impacto de uma implantação ruim para uma única região, permitindo o rollback antes de impactar todos os usuários.
Configurar um pipeline para suportar um modelo de desenvolvimento baseado em "trunk", garantindo que o branch principal seja sempre implantável.
→Configure um gatilho CI no branch `main`. Imponha PRs com uma política de validação de build que execute testes rápidos e abrangentes. Integre notificações rápidas (por exemplo, para Teams/Slack) para falhas de build.
Por quê: O feedback imediato é crítico no desenvolvimento baseado em "trunk". Esta combinação evita que código quebrado seja mesclado e garante uma rápida remediação quando ocorrem problemas.
Passar artefatos grandes (por exemplo, modelos de ML, >5GB) entre os estágios do pipeline de forma eficiente.
→Carregue o artefato grande para o Azure Blob Storage no estágio produtor. Passe o URI do blob para o estágio consumidor como uma variável de saída.
Por quê: O Azure Blob Storage é mais econômico e performático do que os artefatos de pipeline integrados para arquivos de vários gigabytes.
Reduzir os tempos de build, evitando o download repetido de dependências (por exemplo, NuGet, npm) a cada execução.
→Use a tarefa `Cache@2`. Defina uma chave baseada no arquivo de bloqueio do pacote (por exemplo, `packages.lock.json`). A tarefa armazenará e restaurará a pasta de dependências.
Por quê: Pode economizar vários minutos por build, restaurando de um cache local rápido em vez de buscar de repositórios externos.
Compilar ou implantar o mesmo código em vários alvos (por exemplo, diferentes sistemas operacionais, regiões) em paralelo.
→Use uma `strategy: matrix` no job do pipeline YAML. Defina variáveis para cada combinação, o que gerará um job para cada entrada da matriz.
Por quê: Uma estratégia de matriz mantém a definição do pipeline DRY, criando múltiplas variações de job a partir de uma única definição e executando-as em paralelo.
Implementar uma implantação canary no AKS que automaticamente alterna o tráfego e promove ou reverte com base em métricas em tempo real.
→Use um controlador de entrega progressiva como Flagger, integrado com uma "service mesh" (por exemplo, Istio) e um provedor de métricas (por exemplo, Prometheus).
Por quê: Flagger automatiza todo o processo de análise canary, fornecendo entrega progressiva mais segura e confiável do que scripts manuais.
Um pipeline de aplicativo precisa ser acionado quando o código é alterado em seu próprio repositório OU em um repositório de biblioteca compartilhado separado.
→No YAML do aplicativo, defina a biblioteca compartilhada em `resources.repositories` e configure um bloco `trigger` nesse recurso.
Por quê: Cria uma dependência declarativa entre repositórios, garantindo que o aplicativo seja sempre reconstruído com os componentes compartilhados mais recentes.
Um pipeline precisa criar infraestrutura temporária para teste e garantir que ela seja destruída depois, mesmo que os testes falhem.
→Use um pipeline multi-estágios com estágios separados de "apply" e "destroy" para IaC (Terraform/Bicep). Configure o estágio de "destroy" com `condition: always()`
Por quê: A condição `always()` garante que o estágio de limpeza seja executado independentemente do sucesso ou falha dos estágios anteriores, evitando recursos órfãos.
Impedir que uma implantação em produção prossiga, a menos que haja uma solicitação de mudança aprovada em uma ferramenta ITSM como ServiceNow.
→Configure um "Environment gate" que invoca o "Query ServiceNow" gate para verificar o status da solicitação de mudança.
Por quê: Automatiza a integração com processos de gerenciamento de mudanças corporativas, garantindo conformidade sem transferências manuais.
Fornecer um pool de agentes de build self-hosted que escala dinamicamente com a demanda para reduzir tempos de fila e controlar custos.
→Configure um pool de agentes do Azure DevOps usando um Azure Virtual Machine Scale Set (VMSS), configurado para escalar automaticamente com base no número de jobs pendentes.
Por quê: Agentes VMSS combinam a personalização de agentes self-hosted com a elasticidade de agentes hospedados na nuvem, otimizando desempenho e custo.
Implantar alterações de esquema de banco de dados de forma a prevenir perda de dados e suportar rollbacks.
→Use uma ferramenta de migração (por exemplo, Flyway, DbUp). Implemente o padrão "expand/contract" para alterações de esquema para manter a compatibilidade com versões anteriores.
Por quê: Ferramentas de migração fornecem versionamento e controle. O padrão "expand/contract" desacopla rollbacks de aplicação e banco de dados, permitindo implantações mais seguras.
Agentes self-hosted estão ficando sem espaço em disco devido a artefatos de build acumulados.
→No YAML do pipeline, no nível do job, configure `workspace: clean: all`.
Por quê: Esta configuração preventiva de pipeline resolve a causa raiz sem exigir intervenção manual ou mudanças contínuas na infraestrutura.
Testes de integração exigem uma instância de banco de dados isolada para cada execução do pipeline.
→Defina um recurso de contêiner (por exemplo, SQL Server, Postgres) como um serviço no YAML do pipeline. O job de teste pode então se conectar a este serviço efêmero.
Por quê: Fornece dependências rápidas, isoladas e automaticamente limpas para testes, prevenindo interferência de teste e simplificando a configuração.
Melhorar a confiabilidade e o desempenho da restauração de pacotes de repositórios públicos (por exemplo, npmjs, nuget.org).
→No Azure Artifacts, crie um feed e configure fontes upstream apontando para os repositórios públicos. Faça com que os clientes consumam pacotes do feed do Azure Artifacts.
Por quê: O feed armazena em cache pacotes de fontes upstream, protegendo contra interrupções de repositórios públicos e acelerando as restaurações para pacotes frequentemente usados.
Implantar um Helm chart em múltiplos ambientes (dev, prod) com diferentes valores de configuração.
→Use arquivos `values-<env>.yaml` separados para cada ambiente. Na tarefa `HelmDeploy`, use a entrada `valueFile` para especificar o arquivo apropriado e `overrideValues` para injetar valores dinâmicos como tags de imagem.
Por quê: Este padrão separa a configuração estática do ambiente de variáveis dinâmicas de pipeline, mantendo as implantações limpas e de fácil manutenção.