Modern software delivery não é mais limitado pelo código da aplicação — é limitado pela plataforma que o executa. Este artigo apresenta o design de uma Internal Developer Platform (IDP) cloud native construída sobre Kubernetes e o ecossistema CNCF, demonstrando como Infrastructure as Code (IaC), GitOps e pipelines com foco em segurança podem ser combinados em uma plataforma coesa e operacionalmente consistente. Embora algumas implementações usem AKS gerenciado, os padrões arquiteturais se aplicam igualmente a qualquer distribuição Kubernetes conforme CNCF.
TL;DR — Este artigo apresenta o design de uma Internal Developer Platform (IDP) cloud native baseada em Kubernetes, GitOps (Argo CD) e segurança integrada ao ciclo de vida. A conclusão principal para equipes brasileiras: a separação clara entre camadas de infraestrutura, plataforma e aplicação, combinada com políticas de segurança desde o build, reduz drift, acelera deploys e melhora a confiabilidade operacional — desde que a adoção de ferramentas seja guiada pela arquitetura, não pelo hype.
Sistemas distribuídos modernos enfrentam desafios operacionais que motivaram este design de plataforma: inconsistências de deployment entre ambientes causadas por processos manuais; falta de versionamento de infraestrutura e controle de drift, levando à divergência entre ambientes; secrets hardcoded e uma postura de segurança frágil embutida nos pipelines de CI/CD; estratégias de scaling ineficientes que geram custos desnecessários; mecanismos limitados de disaster recovery e rollback quando deploys falham; e observabilidade fragmentada que torna a análise de causa raiz lenta e não confiável. A arquitetura descrita aqui endereça cada uma dessas lacunas por meio de controles declarativos, automatizados e orientados por políticas.
Quais princípios guiaram o design?
A plataforma segue princípios alinhados ao CNCF que orientaram cada decisão arquitetural:
- Infraestrutura declarativa — todos os recursos são versionados e reproduzíveis.
- Deploy baseado em GitOps com Argo CD — Git é a única fonte de verdade para o cluster.
- Infraestrutura imutável e workloads conteinerizados — sem alterações manuais em sistemas em execução.
- Segurança desde o design (security-by-design) em modelagem de ameaças, CI/CD e runtime.
- Observabilidade como capacidade central da plataforma, não um módulo opcional pós-deploy.
- Separação de responsabilidades entre camadas de infraestrutura, plataforma e aplicação por meio de design modular.
Como é a arquitetura de alto nível?
A plataforma é estruturada em três camadas lógicas com clara separação de responsabilidades; colapsar essas camadas cedo introduziu complexidade de manutenção significativa. Isso se reflete em repositórios separados para construir infraestrutura, plataforma e aplicações. A camada de infraestrutura inicializa o controlador GitOps Argo CD. Uma vez inicializado, o Argo CD gerencia o sistema monitorando e reconciliando continuamente tanto os componentes da Plataforma quanto os recursos da camada de Aplicação para corresponder ao estado desejado definido no Git.

Figura 1: Arquitetura completa da plataforma cloud native
1. Camada de infraestrutura
Responsável por provisionar todos os recursos de nuvem usando Terraform, estruturado em módulos reutilizáveis:
- Virtual Networks (VNet), subnets e Network Security Groups
- Managed Kubernetes Cluster
- Container Registry
- Configurações de identidade, acesso e Secret Stores
2. Camada de plataforma
Construída sobre Kubernetes e ferramentas do ecossistema CNCF, instalada e gerenciada declarativamente em repositório separado ou diretórios separados:
- Argo CD — controlador GitOps para reconciliação contínua
- Istio — service mesh para controle de tráfego, mTLS e observabilidade em nível de serviço
- Prometheus — coleta de métricas e alertas
- Grafana — dashboards e visualização
- Loki — agregação centralizada de logs
- Kyverno — Policy as Code na admissão
3. Camada de aplicação
Microserviços implantados como workloads containerizados, gerenciados independentemente via Git:
- Serviços independentemente implantáveis, sem cronogramas de deploy compartilhados
- Empacotamento baseado em Helm para promoção consistente entre ambientes
- Ciclo de vida de deploy orientado pelo Git com trilha de auditoria completa
Fluxo de deployment completo
A plataforma implementa um workflow de entrega em múltiplos estágios que impõe separação estrita entre build da aplicação, validação de segurança e provisionamento de infraestrutura. Esta seção ilustra como o workflow se propaga a partir da análise estática de código até o deployment.

Estágio 1: Pré-requisitos da plataforma
O workflow começa com um conjunto mínimo de componentes fundamentais necessários para executar a automação e os pipelines:
- Um container image registry para armazenar artefatos versionados e assinados
- Um backend remoto do Terraform para gerenciamento de estado e colaboração em equipe
- Uma conexão segura de serviço do provedor de nuvem para execução do pipeline
Estágio 2: Pipeline da aplicação
O pipeline da aplicação é acionado a cada commit nos repositórios da aplicação (serviços Java ou Angular). Sua responsabilidade é produzir uma imagem de container segura, validada e implantável. Cada alteração passa pelos seguintes estágios:
- Build e compilação do código-fonte
- Testes unitários e de integração
- Static Application Security Testing (SAST) — ex.: análise de código
- Varredura de vulnerabilidades de dependências com Trivy
- Criação da imagem de container
- Assinatura da imagem usando Cosign para garantir integridade e proveniência
- Publicação da imagem assinada no container registry
Apenas artefatos verificados, versionados e à prova de adulteração são introduzidos na plataforma. A configuração abaixo mostra as etapas de assinatura Cosign usadas no pipeline.
Cosign image signing and verification
# Stage 1: Build the container image
- task: Docker@2
displayName: 'Build Container Image'
inputs:
command: build
repository: $(ACR_NAME).azurecr.io/$(IMAGE_NAME)
tags: $(Build.BuildId)
# Stage 2: Fetch OIDC token via Workload Identity Federation
- task: AzureCLI@2
displayName: 'Fetch OIDC Token'
inputs:
azureSubscription: '$(SERVICE_CONNECTION)'
scriptType: bash
scriptLocation: inlineScript
addSpnToEnvironment: true
inlineScript: |
echo "##vso[task.setvariable variable=AZURE_FEDERATED_TOKEN;issecret=true]$AZURE_FEDERATED_TOKEN"
# Stage 3: Sign image with Cosign (keyless via Azure Pipelines OIDC)
- script: |
cosign sign \
--yes \
--identity-token=$AZURE_FEDERATED_TOKEN \
$(ACR_NAME).azurecr.io/$(IMAGE_NAME):$(Build.BuildId)
displayName: 'Sign Image with Cosign'
env:
AZURE_FEDERATED_TOKEN: $(AZURE_FEDERATED_TOKEN)
Estágio 3: Pipeline de validação de segurança
Antes de qualquer deployment ou alteração de infraestrutura ser executada, um pipeline dedicado de validação de segurança impõe uma camada adicional de confiança. Esse pipeline valida tanto artefatos quanto configurações de deployment:
- Verificação das assinaturas das imagens de container usando Cosign
- Varredura de vulnerabilidades da imagem com Trivy contra um limite de severidade definido
- Validação de manifests Kubernetes usando KubeSec para detectar padrões de configuração inseguros
Apenas workloads que passam todas as três verificações são considerados conformes e elegíveis para deployment.
Estágio 4: Pipeline de provisionamento de infraestrutura
Assim que a validação de segurança é bem-sucedida, o pipeline de provisionamento de infraestrutura é acionado. Este estágio estabelece a base Kubernetes:
- Provisionamento de rede virtual (VNets, subnets, roteamento)
- Deployment de um cluster k8s gerenciado com node pools de auto-scaling
- Instalação do Argo CD como controlador GitOps
- Inicialização dos CRDs de Application do Argo CD
- Conexão dos repositórios Git de infraestrutura ao Argo CD
O módulo Terraform abaixo reflete a configuração utilizada, incluindo integração com Key Vault via CSI driver e política de rede Calico:
Terraform k8s cluster Module (modules/aks/main.tf)
resource "azurerm_kubernetes_cluster" "main" {
name = var.cluster_name
resource_group_name = var.resource_group_name
default_node_pool {
name = "system"
auto_scaling_enabled = true
min_count = 2
max_count = 10
}
identity {
type = "SystemAssigned"
}
network_profile {
network_plugin = "azure"
network_policy = "calico"
}
key_vault_secrets_provider {
secret_rotation_enabled = true
}
}
Estágio 5: Modelo de deployment GitOps
Após o provisionamento da infraestrutura, a plataforma segue um modelo GitOps onde o Git é a única fonte de verdade. O Argo CD reconcilia continuamente os componentes da camada de plataforma e aplicação monitorando manifests Kubernetes e Helm charts. Alterações enviadas ao Git são automaticamente aplicadas aos clusters ativos, garantindo que o cluster permaneça sincronizado. Isso permite:
- Reconciliação automatizada sem uso manual de kubectl
- Auditabilidade completa via histórico do Git e status de sync
- Rollbacks fáceis usando workflows Git padrão
O CRD Application do Argo CD abaixo mostra como um microserviço é configurado para sync automatizado com self-healing e pruning habilitados:
Argo CD Application CRD — Automated GitOps Sync
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: microservice-api
namespace: argocd
labels:
app.kubernetes.io/part-of: internal-developer-platform
spec:
project: default
source:
repoURL: https://github.com/your-org/gitops-repo
targetRevision: main
path: apps/microservice-api/overlays/production
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true # Remove resources deleted from Git
selfHeal: true # Revert manual changes to cluster
syncOptions:
- CreateNamespace=true
- PrunePropagationPolicy=foreground
retry:
limit: 5
backoff:
duration: 5s
factor: 2
maxDuration: 3m
Estágio 6: Fluxo de requisições em runtime
Uma vez que a infraestrutura e os workloads da aplicação são implantados, usuários externos enviam requisições ao load balancer da nuvem, que encaminha o tráfego para a camada de API Gateway ou Ingress. O gateway mapeia URLs e serviços para os Kubernetes Services apropriados, que então distribuem as requisições entre os Pods saudáveis da aplicação para processamento e resposta.
Arquitetura de segurança
Segurança é tratada como uma preocupação transversal integrada ao longo de todo o ciclo de vida da plataforma — não uma camada aplicada após o deployment. A abordagem abrange integridade da supply chain, enforcement de políticas, proteção em runtime e gerenciamento de secrets.

1. Segurança da supply chain
A segurança começa no nível do artefato, garantindo que apenas componentes confiáveis e verificados entrem no sistema:
- Trivy escaneia imagens de container e dependências em busca de vulnerabilidades conhecidas
- KubeSec valida manifests Kubernetes para identificar configurações inseguras no início do ciclo de vida
- Cosign fornece assinatura criptográfica e verificação de imagens de container, garantindo integridade e proveniência por meio de keyless signing via OIDC
Juntos, esses controles garantem que apenas artefatos escaneados, validados e assinados sejam elegíveis para deployment.
2. Políticas com Kyverno
No nível do cluster, o Kyverno impõe políticas no momento da admissão, impedindo que workloads não conformes sejam agendados. A política abaixo impõe um dos padrões de baseline — não permitir o uso da tag 'latest' em todos os pods:
Kyverno ClusterPolicy — Disallow Latest Tag
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-latest-tag
annotations:
policies.kyverno.io/title: Disallow Latest Tag
policies.kyverno.io/description: >-
Require image tags to be pinned to a specific version.
The 'latest' tag is mutable and can lead to unpredictable deployments.
spec:
validationFailureAction: Enforce
background: true
rules:
- name: require-image-tag
match:
any:
- resources:
kinds:
- Pod
validate:
message: >-
The 'latest' image tag is not allowed. Specify a versioned tag.
pattern:
spec:
containers:
- image: "*:*"
- name: disallow-latest-tag
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Image tag 'latest' is not permitted."
pattern:
spec:
containers:
- image: "!*:latest"
3. Segurança em runtime
Controles pré-deployment são necessários, mas não suficientes. Mecanismos de segurança em runtime monitoram o comportamento do sistema e detectam anomalias durante a execução dos workloads:
- Falco fornece detecção em tempo real de atividades suspeitas dentro dos containers e no ambiente host, com alertas integrados à stack de observabilidade
- AppArmor impõe perfis de segurança em nível de kernel para restringir capacidades dos containers e reduzir a superfície de ataque
4. Gerenciamento de secrets
Dados sensíveis são gerenciados fora dos artefatos de aplicação e deployment para eliminar o risco de exposição:
- Key Vault, integrado via CSI Secrets Store driver, fornece injeção segura e dinâmica de secrets nos workloads na inicialização do pod
- Secrets nunca são armazenados em repositórios Git ou embutidos em imagens de container
- A rotação de secrets é tratada centralmente no Key Vault e capturada automaticamente pelos workloads em execução
Essa abordagem garante que o gerenciamento de secrets permaneça centralizado, auditável e seguro por design.
5. Rede e gerenciamento de tráfego
A camada de rede combina primitivas nativas do Kubernetes com as capacidades do service mesh Istio para fornecer gerenciamento de tráfego seguro, observável e orientado por políticas:
- Kubernetes Services expõem workloads internamente com descoberta DNS estável
- Azure Load Balancer fornece entrada externa com proteção DDoS no perímetro da rede
- Istio gerencia roteamento de tráfego, criptografia mTLS entre serviços e observabilidade em nível de serviço
- Calico CNI impõe políticas de rede, restringindo movimento lateral entre namespaces
Uma lição importante do Istio mTLS: ativar o modo Strict em todo o cluster muito cedo causou problemas de conectividade porque nem todos os workloads tinham sidecar injetado. O Istio suporta o modo Permissive (aceita tanto plaintext quanto mTLS) e o modo Strict (exige apenas mTLS). A correção foi começar no modo Permissive e depois aplicar gradualmente PeerAuthentication em modo Strict por namespace, após confirmar a injeção completa de sidecar em cada namespace.
Stack de observabilidade
Observabilidade é implementada como um sistema unificado com três sinais complementares, todos alimentando uma interface compartilhada do Grafana:
| Ferramenta | Tipo de Sinal | Uso Principal |
|---|---|---|
| Prometheus | Métricas | Utilização de recursos, tracking de SLO, alertas |
| Grafana | Visualização | Dashboards, relatórios de SLA, resposta a incidentes |
| Loki | Logs | Agregação centralizada de logs, correlação com traces |
Adotamos Prometheus, Grafana e Loki para alinhar com um modelo de observabilidade nativo do Kubernetes. Prometheus lida com métricas, Loki com agregação de logs usando indexação leve baseada em labels, e Grafana fornece uma camada de visualização unificada. Isso reduz custo operacional e complexidade em comparação com a manutenção de uma stack separada de Elasticsearch e Kibana.
Estratégia de Infrastructure as Code
O Terraform é estruturado em módulos que refletem as camadas modulares da plataforma, permitindo versionamento e testes independentes de cada um:
| Módulo | Responsabilidade |
|---|---|
| network | VNet, subnets, NSGs, configurações de peering |
| Managed k8s Cluster | Cluster K8s, node pools, RBAC, integração com Key Vault |
| security | Políticas, Defender for Containers, logging de auditoria |
| platform-services | Argo CD, Istio, Prometheus, Grafana, Loki, Kyverno |
A separação de ambientes é tratada usando arquivos de variáveis por ambiente:
- dev.tfvars — contagens reduzidas de nodes, políticas mais relaxadas, iteração mais rápida
- staging.tfvars — topologia equivalente à produção com carga sintética
- prod.tfvars — node pools completos, políticas estritas, schedules de backup habilitados
Essa estrutura garante reusabilidade, consistência entre ambientes e customização controlada por ambiente sem duplicar código de módulo.
Resultados-chave
Os seguintes resultados foram observados em nossos ambientes internos de lab e staging após a adoção completa da plataforma:
| Métrica | Mudança Observada |
|---|---|
| Confiabilidade do deployment | Melhorou para ~95% de sucesso (de ~70% com processos manuais) |
| Tempo de provisionamento de infraestrutura | Reduzido de horas/dias para menos de 15 minutos via automação Terraform |
| Frequência de deployment | Aumentou de semanal para múltiplas versões por dia |
| Incidentes de configuration drift | Quase zero — eliminados pela reconciliação contínua do GitOps |
| Detecção de vulnerabilidades em pré-produção | 80% dos achados capturados antes de chegar ao staging |
| Operações manuais com kubectl | Reduzidas a quase zero para deployments rotineiros |
Desafios e lições aprendidas
Navegar pelo ecossistema CNCF mostrou o risco de adotar muitas ferramentas sobrepostas cedo demais. A principal lição foi deixar a arquitetura guiar as escolhas de ferramentas e adiar adições como OpenTelemetry até a plataforma se estabilizar. Manter a separação clara entre as camadas de infraestrutura, plataforma e aplicação foi essencial para a manutenibilidade de longo prazo. O acoplamento precoce de ferramentas como Argo CD e Istio com o código da aplicação aumentou a complexidade e foi corrigido posteriormente dividindo repositórios em pastas diferentes. O GitOps melhorou a consistência e a rastreabilidade, mas introduziu problemas de sincronização durante a reestruturação de repositórios. Esses problemas foram resolvidos usando o padrão app-of-apps do Argo CD e health checks. Mover as verificações de segurança para etapas iniciais do pipeline — usando Trivy e KubeSec imediatamente após o build — melhorou a velocidade do feedback e reduziu falhas em estágios avançados.
Conclusão
Esta arquitetura mostra como Kubernetes e ferramentas CNCF podem ser combinadas para construir uma plataforma segura, automatizada e escalável, onde o valor real vem de como deployment, segurança e observabilidade funcionam juntos como um sistema. As decisões centrais de design são: estabelecer uma separação clara de camadas desde o início, integrar segurança desde o começo e adotar GitOps com Argo CD desde o primeiro dia. Melhorias futuras focam em gerenciamento multi-cluster com ApplicationSets do Argo CD, enforcement de políticas mais forte com Kyverno, redes zero-trust mais profundas via Istio e a adição de tracing distribuído com OpenTelemetry integrado à stack de observabilidade.
Perguntas Frequentes
-
Qual a principal vantagem de separar as camadas de infraestrutura, plataforma e aplicação?
A separação evita o acoplamento precoce entre ferramentas como Argo CD e Istio com o código da aplicação. Isso reduz a complexidade de manutenção e permite que cada camada evolua de forma independente, com versionamento e testes dedicados. -
Como garantir que a segurança não seja um gargalo no pipeline?
Deslocando as verificações para etapas iniciais do pipeline (shift-left): usar Trivy e KubeSec logo após o build, e assinar imagens com Cosign antes do deploy. Assim, 80% das vulnerabilidades são detectadas antes de chegar ao staging, reduzindo retrabalho. -
Qual o risco de ativar mTLS em modo Strict muito cedo?
Pode causar falhas de conectividade se nem todos os workloads tiverem sidecar do Istio injetado. A abordagem recomendada é começar em modo Permissive e migrar gradualmente para Strict por namespace, após confirmar a injeção completa. -
O que fazer quando a adoção de GitOps causa problemas de sincronização durante reestruturação de repositórios?
Usar o padrão app-of-apps do Argo CD combinado com health checks. Isso mantém a consistência mesmo quando os repos são reorganizados, pois o controlador reconcilia a partir do estado desejado definido no Git.
Artigo originalmente publicado por Abu Hena Mostafa Kamal, CNCF Kubestronaut and Senior Software Engineer em Cloud Native Computing Foundation.