Arquitectura de Plataforma CI/CD y GitOps
Estado: CONFIDENCIAL / USO INTERNO
Área: Arquitectura de TI - DevOps & Infraestructura
Frameworks de Referencia: TOGAF 10, MoProSoft Nivel 4, C4 Model, GitOps Practitioner Standards
1. Objetivo de la Arquitectura
El objetivo primordial de esta arquitectura es establecer una plataforma de Integración Continua (CI) y Entrega Continua (CD) estandarizada, resiliente y altamente segura que sirva como habilitadora tecnológica para toda la organización.
Mediante la adopción de principios de GitOps (Pull-Based), DevSecOps y Continuous Delivery, buscamos mitigar los riesgos operativos, eliminar el factor de error humano en los despliegues, asegurar la conformidad reglamentaria y acelerar el Time-to-Market mediante un flujo continuo, transparente y totalmente auditable.
2. Arquitectura General e Interacciones
La plataforma orquesta múltiples herramientas líderes en la industria para conformar un ecosistema desacoplado pero altamente sincronizado. A continuación, se detalla el flujo lógico de interacción entre los sistemas:
Descripción de los Componentes
- GitHub Enterprise: Repositorio central e inmutable. Actúa como la Única Fuente de Verdad (SSOT) para aplicaciones (código base) y configuraciones (manifiestos).
- Jenkins: Ejecuta la compilación de código, pruebas automáticas, auditoría estática y el empaquetado de contenedores. Nota crítica: Jenkins carece de credenciales e interactividad directa con los clústeres de Kubernetes productivos.
- SonarQube: Evalúa la calidad, mantenibilidad y seguridad del código estático mediante Quality Gates obligatorios.
- Nexus Repository / Docker Registry: Repositorios de almacenamiento para paquetes (JAR, NPM) e imágenes inmutables de Docker (con firmas digitales).
- Argo CD: Controla la reconciliación continua. Vive dentro de Kubernetes y jala los cambios desde Git de forma síncrona.
- WSO2 API Manager: Expone, protege y gobierna el ciclo de vida de las APIs desplegadas en el clúster.
3. Organización de GitHub
La jerarquía organizativa en GitHub Enterprise está diseñada para respetar estrictamente el principio de menor privilegio, permitiendo la autonomía de los equipos sin comprometer la seguridad empresarial.
Tabla de Permisos y Responsabilidades
| Rol Organizacional | Team en GitHub | Repositorios Destino | Permiso | Responsabilidades Clave |
|---|---|---|---|---|
| Enterprise DevOps Architect | DevOps | Todos los repositorios, configs globales de GHE | Admin | Definición de flujos, administración de integraciones, mantenimiento de ArgoCD y Jenkins. |
| Arquitecto de Software | Arquitectura | arq-*, msa-infra-gitops (DEV/UAT) | Maintain | Validación de estándares de desarrollo, creación de plantillas de microservicios, aprobación de arquitectura GitOps. |
| Tech Lead / Dev Senior | Backend / Frontend | Repositorios específicos de código del proyecto | Write (Ramas protegidas vía PR) | Revisión de código (Code Review), aprobación de Merge a develop e inicio de flujo a release. |
| Desarrollador (Jr/Mid) | Backend / Frontend | Repositorios específicos de código del proyecto | Write (Solo ramas feature/* y bugfix/*) | Escritura de lógica de negocio, pruebas unitarias locales, creación de Pull Requests. |
| Product Owner (PO) | Negocio | msa-infra-gitops (PROD) | Read (Aprobador funcional en PR) | Validación funcional de funcionalidades liberadas y firma de aprobación final (Sign-off). |
| QA Engineer | Aseguramiento Calidad | Automatización de pruebas y reporte de Bugs | Read | Validación de ambiente UAT, pruebas de regresión, certificación de estabilidad técnica. |
4. Estrategia de Branching (GitFlow Adaptado)
La organización adopta un modelo de GitFlow modificado para sincronizarse de manera eficiente con los entornos de ejecución (DEV, UAT, PROD).
main: Contiene el código de producción. Solo recibe fusiones de ramasrelease/*ohotfix/*.release/v*.*.*: Ramas de congelamiento de código destinadas a pruebas en el entorno de UAT.develop: Rama principal de integración para el entorno de desarrollo.feature/*: Desarrollo de nuevas capacidades. Nace dedevelopy se reintegra adevelop.hotfix/*: Corrección de errores críticos en producción. Nace demainy se integra de inmediato amainydevelop.bugfix/*: Parche de bugs detectados durante el ciclo de pruebas en UAT. Nace derelease/*y se reintegra a la misma.
5. Estructura y Separación de Repositorios
Para cumplir con el principio de desacoplamiento de GitOps, cada componente de software está aislado en su propio ciclo de vida:
[Ecosistema de Repositorios]
├── Repositorios de Código Fuente (App Repos)
│ ├── msa-sales-backend/ (Código Spring Boot, Jenkinsfile, Dockerfile)
│ └── app-sales-portal/ (Código React/NextJS, Jenkinsfile, Dockerfile)
├── Repositorios de Infraestructura y Configuración (Ops Repos)
│ ├── enterprise-terraform/ (Arquitectura Cloud, Redes, GKE/AKS clusters)
│ ├── enterprise-helm-library/ (Charts base y globales reutilizables)
│ ├── msa-infra-gitops/ (Manifiestos Kubernetes por ambiente y configuración de Argo CD)
│ └── wso2-api-manager-code/ (Declaraciones OpenAPI/Swagger y políticas de API Gateway)
Análisis Técnico de Separación de Repositorios
| Tipo de Repositorio | Propósito Técnico | Ventajas Principales | Desventajas / Retos |
|---|---|---|---|
| Código Aplicativo (Back/Front) | Almacenar código de negocio, pruebas unitarias, Dockerfile de empaquetado y definición del pipeline de CI. | Desacoplamiento total del desarrollo; los devs solo operan dentro de su contexto de código; compilaciones ágiles. | Requiere un pipeline automatizado para transferir las referencias de imágenes construidas al repositorio GitOps. |
| Infraestructura (Terraform) | Aprovisionar y mantener el estado de la infraestructura cloud/física global. | Modularidad en la creación de recursos; rastreo de cambios históricos de infraestructura; prevención de drift cloud. | Alto riesgo si hay merges accidentales; requiere un pipeline de ejecución y planificación extremadamente estricto. |
| Plantillas Helm (Library) | Mantener plantillas estandarizadas de despliegues (Deployment, Service, Ingress, PodDisruptionBudget). | Consistencia organizacional. Si se actualiza una política de seguridad, se cambia en el template global y la heredan todos. | Curva de aprendizaje técnica alta para desarrolladores; gestión compleja de retrocompatibilidad. |
| Declaración de APIs (WSO2) | Definición de APIs, versionado y políticas de seguridad (API-as-Code). | Permite documentar, versionar y publicar APIs directamente mediante flujos automáticos sin intervención manual del portal. | Requiere sincronización precisa con los deployments de backend en Kubernetes para evitar errores 404/502. |
| Estructura de GitOps | Contiene el estado deseado exacto de los entornos de Kubernetes (Kustomize/Helm values). | Seguridad máxima (ningún desarrollador toca producción directamente); auditoría limpia; restauración de desastres instantánea. | Complejidad de promoción de entornos; requiere estrategias de sincronización avanzadas (App of Apps). |
6. Pipeline de Integración Continua (Jenkins CI)
El pipeline de CI se define mediante un archivo de configuración declarativo (Jenkinsfile) que se ejecuta de manera efímera dentro del clúster de Kubernetes como un Pod dinámico.
Ejemplo de Configuración Real: Jenkinsfile Declarativo Empresarial
pipeline {
agent {
kubernetes {
yaml '''
apiVersion: v1
kind: Pod
metadata:
labels:
some-label: jenkins-agent
spec:
containers:
- name: maven
image: maven:3.9.6-eclipse-temurin-17
command: ['cat']
tty: true
- name: docker
image: docker:24.0.7-dind
securityContext:
privileged: true
command: ['cat']
tty: true
- name: trivy
image: aquasec/trivy:0.48.1
command: ['cat']
tty: true
'''
}
}
environment {
DOCKER_REGISTRY = 'registry.alpura.com'
IMAGE_NAME = 'msa-sales-backend'
SONAR_PROJECT = 'alpura-msa-sales-backend'
GITOPS_REPO = 'github.com/alpura-enterprise/msa-infra-gitops.git'
CREDENTIALS_ID = 'jenkins-github-ssh'
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Build & Compilation') {
steps {
container('maven') {
sh 'mvn clean compile -DskipTests'
}
}
}
stage('Unit Tests & Coverage') {
steps {
container('maven') {
sh 'mvn test jacoco:report'
}
}
}
stage('SonarQube Quality Gate') {
steps {
container('maven') {
withSonarQubeEnv('SonarQube-Enterprise') {
sh "mvn sonar:sonar -Dsonar.projectKey=${SONAR_PROJECT}"
}
timeout(time: 10, unit: 'MINUTES') {
waitForQualityGate abortPipeline: true
}
}
}
}
stage('Container Image Scan') {
steps {
container('trivy') {
sh "trivy image --severity HIGH,CRITICAL --exit-code 0 ."
}
}
}
stage('Docker Build & Push') {
steps {
container('docker') {
withCredentials([usernamePassword(credentialsId: 'docker-registry-auth', usernameVariable: 'REG_USER', passwordVariable: 'REG_PWD')]) {
sh "docker login ${DOCKER_REGISTRY} -u ${REG_USER} -p ${REG_PWD}"
sh "docker build -t ${DOCKER_REGISTRY}/${IMAGE_NAME}:${BUILD_NUMBER} ."
sh "docker push ${DOCKER_REGISTRY}/${IMAGE_NAME}:${BUILD_NUMBER}"
}
}
}
}
stage('Update GitOps Manifest') {
steps {
withCredentials([gitUsernamePassword(credentialsId: 'github-app-token', gitToolName: 'git-tool')]) {
sh """
git config --global user.email "devops-bot@alpura.com"
git config --global user.name "Alpura DevOps Bot"
git clone https://${GITOPS_REPO}
cd msa-infra-gitops/apps/${IMAGE_NAME}/overlays/dev
sed -i 's|newTag:.*|newTag: "${BUILD_NUMBER}"|g' kustomization.yaml
git add kustomization.yaml
git commit -m "chore(cd): promote ${IMAGE_NAME} to version ${BUILD_NUMBER} in dev"
git push origin dev
"""
}
}
}
}
post {
always {
cleanWs()
}
}
}
7. Pipeline de Entrega Continua (Argo CD CD)
Argo CD ejecuta la conciliación continua detectando el estado deseado en Git y forzándolo en el clúster mediante un flujo estructurado:
Definición del Manifiesto: Argo CD Application
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: msa-sales-backend-prod
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: sales-domain
source:
repoURL: 'https://github.com/alpura-enterprise/msa-infra-gitops.git'
targetRevision: main
path: apps/msa-sales-backend/overlays/prod
destination:
server: 'https://kubernetes.default.svc'
namespace: sales-prod
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
- PrunePropagationPolicy=foreground
- PruneLast=true
retry:
limit: 5
backoff:
duration: 10s
factor: 2
maxDuration: 3m
8. Flujo y Gobierno GitOps Completo
Flujo de Liberación y Aprobaciones Completo
El siguiente flujo gráfico detalla de forma exhaustiva el camino que recorre un cambio en la organización, desde que el desarrollador crea el código hasta su ejecución final estable en Kubernetes.
[ REPOSITORIO DE APLICACIÓN ]
│
├──> 1. Crea Rama Feature <─── [ Dev Junior / Mid / Senior ]
│
├──> 2. Pull Request (PR) a Main o Develop
│ │
│ └──> 📑 APROBACIÓN REQUERIDA (Code Review)
│ └──> Mínimo:
│ • Dev Senior o Tech Lead
│ • Arquitecto de Software
│
└──> 3. Pipeline CI (Jenkins)
│
├── Checkout
├── Build & Compile
├── Unit Test
├── Static Analysis (SonarQube)
├── Quality Gate (Falla si no cumple)
├── Build Docker Image
├── Vulnerability Scan (Trivy/Snyk)
├── Push Docker Registry
└── Actualiza automáticamente el repositorio GitOps
│
▼
[ REPOSITORIO DE CONFIGURACIÓN (GitOps) ]
│
├── Manifiestos Kubernetes (Kustomize Overlays)
├── Helm Charts base y globales
├── Valores por ambiente (values-dev.yaml, values-prod.yaml)
├── Estructura de Namespaces, Network Policies
└── Versiones de imágenes por contenedor (Inmutables)
│
├──> 4. Pull Request (Automático o Manual de Promoción)
│
│ └── 🔐 AUTORIZACIÓN OBLIGATORIA
│
│ • Arquitecto Enterprise
│ • Product Owner (PO)
│
│ Ambos deben firmar con Check en GitHub para avanzar a PROD.
│
└──> 5. Merge a Rama Main del Repo GitOps
│
▼
[ OPERADOR GITOPS ]
Argo CD (Instalado internamente en K8s)
│
Detecta cambios en Git (Pull cada 3 min o vía Webhook)
│
Compara Estado Actual del Clúster vs Estado Deseado en Git
│
Ejecuta la sincronización (Sync)
│
Rolling Update sin pérdida de servicio
│
Verificación de Health Checks
│
Validación del Deployment y Tráfico
│
▼
Clúster Kubernetes (Estado Deseado Sincronizado)
Diagrama de Secuencia de Procesos de GitOps
Tabla de Gobierno: Pull vs Push
| Criterio de Comparación | Modelo Pull-Based GitOps (ArgoCD) | Modelo Push-Based CI/CD (Jenkins Directo) |
|---|---|---|
| Seguridad del Clúster | Alta: El clúster no expone puertos ni API externa; ArgoCD jala cambios desde dentro. | Baja: El motor CI debe poseer credenciales de Admin del clúster (kubeconfig) expuestas externamente. |
| Auditoría y Trazabilidad | Inmutable: Cada cambio físico en el clúster corresponde exactamente a un commit firmado en Git. | Efímera: Desafíos para correlacionar quién detonó una acción manual de despliegue directo en el servidor CI. |
| Recuperación ante Desastres | Instantánea: Reconstrucción total del clúster en minutos clonando y sincronizando el repo GitOps. | Compleja: Depende de respaldos manuales o de ejecutar múltiples pipelines secuenciales en el orden correcto. |
| Prevención de Drift (Desviación) | Automática: ArgoCD sobrescribe inmediatamente cualquier cambio manual local no declarado en Git. | Inexistente: Si un operador altera un Deployment usando kubectl edit, el motor CI no se entera. |
| Cumplimiento y Gobierno | Garantizado: Toda promoción requiere PR aprobados por roles segregados de arquitectura y negocio. | Débil: El pipeline tiene control total y puede mezclar responsabilidades de desarrollo y despliegue. |
9. Integración con WSO2 API Manager
El gobierno de APIs se integra directamente en el proceso de entrega continua mediante el enfoque API-as-Code, asegurando que los contratos de integración se mantengan y automaticen de forma limpia.
Ciclo de Promoción API-as-Code
- Definición Declarativa: El archivo de especificación OpenAPI (
swagger.yaml) y un archivo de configuración de API de WSO2 (api.yaml) conviven en el repositorio de APIs. - Validación en Pipeline: Jenkins procesa la definición con herramientas de linting para garantizar el cumplimiento de estándares empresariales de nomenclatura y tipado.
- Aprovisionamiento automatizado: La CLI
apictlejecuta la importación o actualización del recurso en el entorno destino:apictl import-api -f ./api-package -e dev --update=true - Políticas globales: Las políticas de seguridad (ejemplo: validación de tokens OAuth2, protección contra inyecciones SQL en API Gateway) se inyectan automáticamente desde las plantillas corporativas.
10. Flujo Completo de una Liberación y Promoción de Entornos
Matriz de Promoción de Entornos
| Entorno destino | Rama de GitOps | Aprobadores Requeridos | Tag de Contenedor | Control de Sincronización | Evidencia Registrada |
|---|---|---|---|---|---|
| DEV | dev | Ninguno (Automático tras Merge en develop de App) | #BUILD_NUMBER (Ej: 122) | Automático (Self-Heal y Prune activos) | Logs de Jenkins y Commit firmado del Bot de DevOps. |
| UAT | uat | Líder Técnico / DevOps Lead | #BUILD_NUMBER (Misma de DEV validada) | Sincronización Automática al aprobar el PR | PR Aprobado en GitHub con aprobación del Tech Lead. |
| PROD | main | Product Owner y Arquitecto Enterprise | #BUILD_NUMBER (Imagen Certificada) | Sincronización Manual (Disparada vía UI/Git o programada) | Registro del PR en GitHub con doble firma aprobatoria y Release Tag generado. |
11. Seguridad y Estrategia DevSecOps
El modelo Shift-Left Security incrusta controles rígidos en cada fase del ciclo de vida del software:
Controles de Seguridad Clave
- CODEOWNERS y Branch Protection: Es imposible inyectar código directo a
develop,release/*omain. Se requiere obligatoriamente aprobación del equipo asignado en el archivoCODEOWNERS:# Archivo CODEOWNERS en GitHub* @alpura-enterprise/devops-architects/src/main/ @alpura-enterprise/backend-leads/pom.xml @alpura-enterprise/backend-leads - Gestión de Secretos: Está estrictamente prohibido commitear contraseñas, tokens o llaves API en Git. Las aplicaciones leen referencias ficticias. Un operador dentro de Kubernetes (External Secrets Operator) se conecta a HashiCorp Vault, recupera los secretos y crea
Secretsnativos efímeros en RAM de K8s. - Firma de Imágenes con Cosign: Las imágenes que pasan con éxito las pruebas y el escaneo de Trivy son firmadas usando una clave privada de organización. Kubernetes (a través de un controlador de admisión como Kyverno) rechaza la ejecución de cualquier contenedor cuya firma no sea verificable.
12. Gestión de Versiones y Estrategia de Rollback
Versionado Semántico (SemVer 2.0.0)
Cada microservicio utiliza el formato MAJOR.MINOR.PATCH:
MAJOR: Cambios incompatibles con la API actual.MINOR: Nuevas funcionalidades retrocompatibles.PATCH: Corrección de errores que no rompen nada.
Flujos de Rollback Comparados
13. Gobierno de Repositorios (Estándares Corporativos)
Para mantener el orden a escala empresarial, todos los repositorios creados bajo la organización alpura-enterprise deben cumplir rigurosamente con los siguientes estándares de gobernanza: