Problema

Muchas organizaciones que empezaron en un único proveedor (Azure o AWS) se ven obligadas a operar en ambos por fusiones, requisitos regulatorios o la necesidad de usar servicios exclusivos. El patrón que surge es una infraestructura fragmentada: cada equipo mantiene su propio conjunto de herramientas, configuraciones de red y políticas de identidad. El resultado típico es:

  • Duplicación de esfuerzos de despliegue.
  • Falta de visibilidad única sobre métricas y alertas.
  • Inconsistencias de seguridad entre los proveedores.
  • Incremento de costos operacionales y de licencia.

En estos setups suele pasar que la presión por “abstraer la nube” lleva a crear capas de compatibilidad que terminan siendo más un lastre que una solución.

Causa

1. Abstracción de servicios sin respetar los modelos nativos

Intentar unificar AKS y EKS bajo una misma API ignora diferencias críticas en networking, escalado y políticas de seguridad. Las abstracciones “leak” y obligan a renunciar a funcionalidades avanzadas.

2. Identidad y control de acceso dispares

Azure AD (Entra ID) y AWS IAM + Okta gestionan usuarios, grupos y roles de forma distinta. Sin un plan de federación, los flujos de SSO y RBAC se vuelven manuales y propensos a errores.

3. Herramientas de observabilidad aisladas

Azure Monitor/Log Analytics y CloudWatch/Datadog no comparten un esquema de datos común. Cuando un incidente ocurre en una nube, el equipo de la otra carece de contexto.

4. Redes diseñadas para un solo proveedor

VNet y Transit Gateway tienen topologías y mecanismos de enrutamiento propios. Pelear por una “red única” sin un plano de interconexión genera latencia y rutas inesperadas.

5. Falta de una política clara de “una nube por carga de trabajo”

Cuando se insiste en que cada servicio sea desplegable en ambas nubes, se duplica la superficie de pruebas y se diluye la expertise del equipo.

Solución

1. Adoptar IaC unificado con Terraform

Terraform funciona como lenguaje declarativo común. La clave es modularizar por proveedor en lugar de abstraerlos. Cada módulo contiene recursos específicos (por ejemplo, azurerm_kubernetes_cluster o aws_eks_cluster) y expone variables estandarizadas (nombre, zona, tags). El flujo de CI/CD (PR → plan → review → apply) permanece idéntico para ambas nubes.

2. Federar identidades mediante OpenID Connect (OIDC)

Configura Azure AD como IdP para AWS y viceversa usando OIDC. Con un único directorio de usuarios, los grupos se sincronizan y los roles de IAM y RBAC se asignan mediante mapeos. Okta puede seguir como broker externo, pero la confianza se establece entre los dos proveedores de nube.

3. Consolidar observabilidad con Grafana Cloud

Grafana Cloud acepta fuentes de datos de Azure Monitor y CloudWatch. Al crear dashboards unificados y alertas que se enrutan a PagerDuty, cualquier operador ve el mismo panel sin importar la nube origen. Usa etiquetas comunes (environment, service) para correlacionar logs.

4. Interconexión de redes mediante Transit Gateway + VNet peering

  • AWS Transit Gateway conectado a Azure VPN Gateway mediante túneles IPsec.
  • BGP para intercambio dinámico de rutas.
  • Mantén subredes separadas por carga de trabajo, pero publica rutas necesarias (por ejemplo, acceso a bases de datos compartidas) en ambas direcciones.

5. Definir una regla de “una nube por workload”

Evalúa cada proyecto contra un checklist de servicios críticos (ML, bases de datos, web). Si la nube A ofrece una ventaja clara (SageMaker, Azure SQL), despliega allí y marca la carga como “primary”. Solo crea recursos en la otra nube cuando sea estrictamente necesario (replicación, disaster recovery).

6. Control de costos con tagging y políticas de presupuesto

Aplica etiquetas obligatorias (owner, cost_center, cloud) y usa Azure Cost Management + AWS Budgets para generar alertas cuando el gasto supera el umbral definido (por ejemplo, 15 % sobre el promedio histórico).

Cuándo aplicar esta solución

  • Síntomas: equipos que gestionan dashboards diferentes, tickets de acceso cruzado, despliegues que fallan por falta de recursos específicos de la nube.
  • Entorno: al menos dos proveedores en producción, con equipos que ya usan Terraform o están dispuestos a adoptarlo.
  • No aplica: cuando la organización planea migrar completamente a una sola nube en el corto plazo; en ese caso, la inversión en federación y observabilidad dual puede ser innecesaria.

Código

# Inicializar Terraform con backend compartido (ejemplo S3 + Azure Storage)
terraform init \
  -backend-config="bucket=my-tf-state" \
  -backend-config="key=global/terraform.tfstate" \
  -backend-config="region=us-east-1" \
  -backend-config="access_key=$AWS_ACCESS_KEY_ID" \
  -backend-config="secret_key=$AWS_SECRET_ACCESS_KEY"

# Plan para Azure
terraform workspace select azure
terraform plan -var='cloud=azure' -out=plan-azure.out

# Plan para AWS
terraform workspace select aws
terraform plan -var='cloud=aws' -out=plan-aws.out

# Aplicar (revisar antes de ejecutar)
terraform apply plan-azure.out
terraform apply plan-aws.out

Verificación

  1. IaC: Después de terraform apply, verifica que los recursos aparecen en ambos portales y que los tags obligatorios están presentes.
  2. Identidad: Inicia sesión en una aplicación que use Azure AD y confirma que el token contiene el claim iss de AWS (OIDC). Repite con un usuario de Okta.
  3. Observabilidad: Abre un dashboard de Grafana y comprueba que métricas de un pod en AKS y de una instancia EC2 aparecen en la misma tabla. Genera una alerta manual y verifica que llega a PagerDuty.
  4. Red: Desde una VM en Azure, haz ping a una instancia en AWS usando la IP privada asignada por el túnel. Confirma que la ruta aparece en la tabla de BGP (show bgp summary).
  5. Costos: Revisa los informes de costos de ambos proveedores y asegura que el gasto mensual está dentro del rango de presupuesto definido.

Notas adicionales

  • Versionado de módulos: Publica los módulos Terraform en un registro interno (GitHub Packages, Artifactory) y usa versiones semánticas para evitar rupturas inesperadas.
  • Rotación de credenciales: Automatiza la rotación de claves de acceso mediante Azure Key Vault y AWS Secrets Manager; enlaza ambos con el pipeline de CI.
  • Pruebas de integración: Implementa pruebas de smoke que desplieguen recursos mínimos en ambas nubes y validen conectividad antes de cualquier release mayor.
  • Documentación viva: Mantén un README por módulo que detalle los parámetros obligatorios y los valores por defecto; evita que nuevos equipos tengan que “adivinar” la configuración.
  • Escalado de observabilidad: Si la carga de logs supera los límites de Grafana Cloud gratuito, considera una instancia auto‑gestionada de Loki o CloudWatch Logs Insights y re‑exporta los datos a Grafana mediante plugins.