aws-wl-htg-nonpro
aws-wl-htg-nonpro es la cuenta AWS que aloja todos los entornos de no producción del proyecto IRIS: desarrollo (dev), entornos efímeros por feature branch (dev-features) y pruebas (test). También aloja servicios auxiliares que solo existen fuera de producción (la instancia SugarCRM de desarrollo).
La estructura es la misma que en producción para que ambas cuentas sean operacionalmente intercambiables: red, EKS, ArgoCD, ECR cross-account, IRSA y External Secrets se comportan igual. La diferencia está en lo que se quita o se relaja: no hay Aurora, las réplicas Redis y MySQL son únicas, no se exige TLS donde no aporta valor y la observabilidad es más ligera.
La infraestructura vive en dos repositorios complementarios:
aws-infrastructure/aws-wl-htg-nonpro/— Terraform: VPC, EKS, RDS, ElastiCache, S3, IAM, EC2.kubernetes-clusters/kubernetes-htg-nonpro/— manifiestos GitOps de la plataforma del cluster.
Datos clave
| Concepto | Valor |
|---|---|
| Cuenta AWS | 913305982008 |
| Alias | aws-wl-htg-nonpro |
| Región | eu-south-2 (Spain) |
| Región ECR (compartida) | eu-west-1 |
| Acceso administrativo | AWS IAM Identity Center → AWSAdministratorAccess |
| Entornos alojados | dev, dev-features, test |
| Repositorio Terraform | aws-infrastructure/aws-wl-htg-nonpro |
| Repositorio GitOps | kubernetes-clusters/kubernetes-htg-nonpro |
Acceso
Igual que en producción, todo el acceso humano va por AWS IAM Identity Center. No existen usuarios IAM con credenciales estáticas.
aws sso login --profile htg-nonpro
aws sts get-caller-identity --profile htg-nonpro
aws eks --region eu-south-2 update-kubeconfig --name htg-nonpro --profile htg-nonpro
kubectl get nodes
El rol SSO AWSAdministratorAccess se mapea al cluster mediante una EKS Access Entry con AmazonEKSClusterAdminPolicy.
Red
La VPC htg-nonpro ocupa 10.10.128.0/18 (no se solapa con htg-pro, que está en 10.10.192.0/18, lo que permitirá VPC peering futuro sin renumerar). Se divide en los mismos tres tipos de subredes replicadas en las tres AZ de eu-south-2:
| Tipo | Función | Tamaño |
|---|---|---|
| Públicas | ALBs, NAT Gateway, bastion | /24 |
| Privadas | Nodos EKS, pods, instancia SugarCRM dev (al estar en pública con EIP, los demás workloads van privados) | /20 |
| Database | Subnet group dedicado a RDS y ElastiCache | /24 |
NAT único (single_nat_gateway = true). Mismo etiquetado que la cuenta productiva: kubernetes.io/role/{elb,internal-elb} para el ALB Controller y karpenter.sh/discovery = htg-nonpro para que Karpenter aprovisione nodos en las subredes correctas.
Cluster EKS
Control plane
| Parámetro | Valor |
|---|---|
| Nombre | htg-nonpro |
| Versión Kubernetes | 1.33 |
| Endpoint público | Habilitado |
| Modo de autenticación | API_AND_CONFIG_MAP |
| OIDC provider | oidc.eks.eu-south-2.amazonaws.com/id/FE5540FF48F49F2BF9DA4A6FDBCEE1C1 |
Arquitectura de cómputo
La estrategia es idéntica a producción — Karpenter sobre Fargate, sin Node Groups gestionados— pero más austera: un único NodePool, sin pool de cómputo dedicado.
graph LR
subgraph Fargate
Karpenter[Karpenter controller]
end
subgraph EC2["Nodos EC2 (Bottlerocket)"]
Default["NodePool default<br/>(t3, spot+on-demand)"]
end
Karpenter -->|aprovisiona| Default
La diferencia operativa frente a htg-pro es que el EC2NodeClass del nonpro fija explícitamente los metadataOptions:
metadataOptions:
httpEndpoint: enabled
httpProtocolIPv6: disabled
httpPutResponseHopLimit: 1
httpTokens: required
Con httpPutResponseHopLimit: 1 se impide que un proceso dentro de un contenedor llegue al endpoint IMDS de la instancia, evitando que pueda obtener credenciales del IAM role del nodo. httpTokens: required fuerza IMDSv2.
Add-ons gestionados
Mismo conjunto que en htg-pro, con dos pequeñas diferencias:
| Add-on | Diferencias con htg-pro |
|---|---|
aws-efs-csi-driver |
Versión por defecto (en htg-pro está fijada a v2.3.1-eksbuild.1) |
aws_cloudwatch_metrics |
Sin tolerations adicionales para karpenter.sh/nodepool (no hay pool con taint) |
EBS y EFS CSI se asocian por Pod Identity a los roles EBS_CSI_DriverRole y EFS_CSI_DriverRole.
Add-ons de plataforma (EKS Blueprints)
Mismo aws-ia/eks-blueprints-addons que en producción: ALB Controller, AWS for Fluent Bit (0.1.35) y CloudWatch Agent.
Fluent Bit está configurado con la misma lógica de pipelines paralelos que htg-pro (parser JSON dedicado para infra-iris-api-*), apuntando a sus propios log groups:
| Log group | Contenido |
|---|---|
/aws/eks/htg-nonpro/infra-iris-api/<namespace> |
Logs estructurados de los entornos iris-api |
/aws/eks/htg-nonpro/aws-fluentbit-logs |
Resto de logs de pods |
Retención fijada a 14 días.
Plataforma GitOps (kubernetes-htg-nonpro)
La capa de plataforma sigue la misma organización que en producción pero con menos piezas: lo justo para que las aplicaciones se desplieguen y se puedan depurar, sin componentes de cost-optimization ni de monitorización avanzada.
platform/ # ArgoCD, External Secrets, Karpenter, KEDA, Reloader
observability/ # PMM
Faltan respecto a htg-pro: Prometheus Operator, Prometheus, Prometheus Adapter y PerfectScale.
ArgoCD
| Parámetro | Valor |
|---|---|
| URL | https://argocd-nonpro.htg-express.com |
| Manifiesto base | argoproj/argo-cd stable/manifests/ha/install.yaml (HA) |
| Ingress | ALB internet-facing, TLS 1.3 |
| Certificado | arn:aws:acm:eu-south-2:913305982008:certificate/f23c4db5-ca20-4368-80b3-a2372fb7b319 |
| Backend | HTTPS con condición Content-Type: application/grpc para argocd-grpc |
| Service gRPC | NodePort argocd-grpc con backend-protocol-version: HTTP2 |
Bootstrap. Igual que en producción:
kubectl apply -k platform/argocd/overlays
Autenticación. Admin local deshabilitado, SAML contra el SSO de IAM Identity Center (entidad y callback contra argocd-nonpro.htg-express.com). Los mismos cuatro grupos están mapeados a los mismos roles que en htg-pro:
| Grupo SSO | Rol ArgoCD |
|---|---|
AWSAdministrators |
role:applications |
ExternalDevTeam |
role:applications |
HTGDevTeam |
role:applications |
Linube |
role:admin |
Acceso a ECR. El mecanismo es idéntico al de htg-pro pero apunta al rol cross-account ecr-access-shared-htg-nonpro:
- ServiceAccount
aws-ac-htg-cicd-ecrcon anotacióneks.amazonaws.com/role-arn: arn:aws:iam::203965864736:role/ecr-access-shared-htg-nonpro. ECRAuthorizationToken(External Secrets) genera un token cada hora sobre ese SA.ExternalSecretaws-ac-htg-cicd-ecrlo materializa con la etiquetaargocd.argoproj.io/secret-type: repository.
El rol cross-account vive en la cuenta CI/CD (913305982008) bajo el módulo ecr_access_htg_nonpro y acepta a los ServiceAccount argocd/aws-ac-htg-cicd-ecr, infra-iris-api-{dev,dev-features,test}-ecr, infra-iris-chat-{dev,test}-ecr, infra-iris-frontend-{dev,dev-features,test}-ecr e infra-iris-myhtg-{dev,test}-ecr.
External Secrets Operator
Mismas características que en htg-pro: valores por defecto, se conecta a AWS Secrets Manager con IRSA y los SecretStore se definen por aplicación.
Karpenter (resources)
Controlador desplegado por Terraform (helm_release.karpenter versión 1.6.0).
EC2NodeClass default con la AMI bottlerocket@latest, IAM role htg-nonpro y autodescubrimiento por karpenter.sh/discovery: htg-nonpro. Como se ha mencionado, fija explícitamente metadataOptions (IMDSv2 con hop limit 1).
NodePool default — único pool de la cuenta:
amd64sobre hypervisor Nitro- Familia
t3enspotyon-demand - Límite global de 64 vCPU
expireAfter: 720h, consolidación tras 1 min, disruption budget 10 %
A diferencia de htg-pro, no hay NodePool de cómputo: las cargas pesadas (procesadores PHP, builders) no existen aquí.
KEDA
A diferencia de producción, htg-nonpro instala KEDA para experimentar con autoescalado basado en eventos (colas, métricas externas). KEDA convive con el HPA estándar y aporta ScaledObjects que pueden disparar el escalado a partir de Redis, SQS, Prometheus remoto, etc.
Configuración relevante de los valores Helm:
- Operator: 2 réplicas en HA, con
PodDisruptionBudget(minAvailable: 1) - Metrics Server: 2 réplicas en HA con PDB
- Webhooks: 2 réplicas con PDB
- Logging en formato JSON para que Fluent Bit lo envíe estructurado
Reloader
Despliegue con valores Helm por defecto, igual que en producción.
Observabilidad
PMM (Percona Monitoring and Management)
Aquí PMM monitoriza las instancias RDS de la cuenta nonpro y se usa también como herramienta de pruebas antes de promover cambios a la PMM de producción. Por eso la versión está fijada explícitamente (en htg-pro se usa el latest gestionado por el operator).
| Parámetro | Valor |
|---|---|
| URL | https://pmm.htg-express.com (mismo host que producción, distinto ALB y certificado) |
| Imagen | percona/pmm-server:3.4.1 |
| Almacenamiento | 25 GiB sobre gp2 |
| ServiceAccount | pmm-service-account → arn:aws:iam::913305982008:role/InfraPmm |
| Certificado | arn:aws:acm:eu-south-2:913305982008:certificate/f23c4db5-ca20-4368-80b3-a2372fb7b319 |
La contraseña del admin se materializa con un ExternalSecret en pmm/pmm-secret desde el secreto infra/pmm (pmmAdminPassword) mediante el rol InfraPmm.
Bases de datos
RDS MySQL — iris-api-dev
Base de datos transaccional compartida por los entornos dev y dev-features del backend.
| Parámetro | Valor |
|---|---|
| Engine | MySQL 8.0.43 |
| Tipo | db.t4g.small |
| Storage | 20 – 30 GiB gp3 |
| Multi-AZ | No |
| Publicly accessible | Sí (controlado por SG) |
| Deletion protection | Habilitado |
| Parameter group | iris-api-dev-params (performance_schema=1, TZ Europe/Paris) |
| Backups | Sí (retención por defecto) |
| Enhanced monitoring | 60s (rol IAM compartido con sugar-crm-dev) |
| Owner tag | linube |
El SG iris-api-dev-db admite ingress desde el cluster EKS, desde el bastion, desde la subred del operador SaaS Qlik (seis rangos IPv4 documentados en el código) y desde el salto operativo de Linube.
RDS MySQL — sugar-crm-dev
Base de datos de la instancia de SugarCRM de desarrollo, que corre sobre la EC2 bs1252.
| Parámetro | Valor |
|---|---|
| Engine | MySQL 8.4.7 |
| Tipo | db.t4g.small |
| Storage | 20 – 30 GiB gp3 |
| Multi-AZ | No |
| Deletion protection | Habilitado |
| Publicly accessible | Sí |
Solo acepta conexiones desde el SG del bastion y desde el SG de bs1252. Reutiliza el rol de Enhanced Monitoring creado por iris-api-dev.
No hay Aurora
A diferencia de htg-pro, no se aprovisiona Aurora Serverless en esta cuenta. Para iris-api-test se utiliza la propia instancia iris-api-dev o una base efímera materializada por la aplicación; los entornos efímeros (dev-features) comparten DB con dev.
Cache (ElastiCache Redis)
Una única instancia Redis simple, sin réplicas ni TLS, suficiente para los entornos de desarrollo y pruebas:
| Parámetro | Valor |
|---|---|
| Replication group | iris-api-dev |
| Engine | Redis 7.1 |
| Tipo de nodo | cache.t3.micro |
| Nodos | 1 |
| Encriptación en reposo | Sí (por defecto del módulo) |
| Encriptación en tránsito | No |
| Parameter group | redis7 por defecto |
| Acceso | Solo desde el SG del cluster EKS |
No hay un cluster separado para queues — al no haber carga real, se comparte.
Almacenamiento (S3)
| Bucket | Entorno | Aplicación |
|---|---|---|
iris-api-files-dev |
dev |
Adjuntos iris-api (Laravel) |
iris-api-files-dev-features |
dev-features |
Adjuntos iris-api para feature branches |
iris-api-files-test |
test |
Adjuntos iris-api |
iris-chat-dev |
dev / dev-features |
Adjuntos iris-chat (compartido) |
iris-chat-test |
test |
Adjuntos iris-chat |
Todos los buckets son privados. El acceso se concede vía IRSA a la aplicación que corresponda; iris-chat-dev aparece referenciado en los roles de dev y dev-features porque ambos entornos lo comparten.
Identidades IAM
Un rol IRSA por entorno y aplicación. El trust policy de cada uno está restringido al sub exacto del ServiceAccount.
| Rol IAM | ServiceAccount | Recursos |
|---|---|---|
EcrReadOnlyRole |
external-secrets/external-secrets |
AmazonEC2ContainerRegistryReadOnly (legacy, mantenido para compatibilidad) |
InfraIrisApiDev |
infra-iris-api-dev/infra-iris-api-dev |
Secrets infraIrisApi/dev/*, S3 (iris-api-files-dev, iris-chat-dev) |
InfraIrisApiDevFeatures |
infra-iris-api-dev-features/infra-iris-api-dev-features |
Secrets infraIrisApi/devFeatures-*, S3 (iris-api-files-dev-features, iris-chat-dev) |
InfraIrisApiTest |
infra-iris-api-test/infra-iris-api-test |
Secrets infraIrisApi/test-*, S3 (iris-api-files-test, iris-chat-test) |
InfraIrisChatDev |
infra-iris-chat-dev/infra-iris-chat-dev |
Secrets infraIrisChat/dev-*, S3 (iris-chat-dev) |
InfraIrisChatTest |
infra-iris-chat-test/infra-iris-chat-test |
Secrets infraIrisChat/test-*, S3 (iris-chat-test) |
InfraPmm |
pmm/pmm-service-account |
Secrets infra/pmm-* |
EBS_CSI_DriverRole |
kube-system/ebs-csi-controller-sa (Pod Identity) |
EBS CSI |
EFS_CSI_DriverRole |
kube-system/efs-csi-controller-sa (Pod Identity) |
EFS CSI |
Para los ServiceAccount infra-iris-*-ecr el rol cross-account es arn:aws:iam::203965864736:role/ecr-access-shared-htg-nonpro (sección Integración con la cuenta CI/CD).
Instancias EC2 auxiliares
bs1245 — Bastion
| Parámetro | Valor |
|---|---|
| AMI | AlmaLinux 9.5 (ami-0fcdf92274127bd3e) |
| Tipo | t3.medium |
| Disco | 50 GiB gp3 |
| EIP | Sí (sin prevent_destroy) |
| Puerto SSH | 27 |
| Acceso | Cuentas nominales + clave personal |
| IMDS | v2 obligatorio |
Está en dos SGs:
bastion: ingress SSH:27 desde0.0.0.0/0y egress total.linube_access: ingress de monitorización y SSH desde la operación de Linube.
Sirve además como salto para tunelizar a las RDS y al Redis privado (las RDS de no producción están en subred database aunque marcadas como publicly_accessible = true; en la práctica el SG bloquea internet).
bs1252 — SugarCRM dev
| Parámetro | Valor |
|---|---|
| AMI | AlmaLinux 9.5 |
| Tipo | t3.2xlarge |
| Disco | 50 GiB gp3 |
| EIP | Sí |
| Puertos abiertos | 80 y 443 desde internet |
| Base de datos | RDS sugar-crm-dev |
SugarCRM funciona como su análogo en producción (SuiteCRM): una pila tradicional fuera del cluster con LAMP y MySQL gestionado.
Integración con la cuenta CI/CD
Los workloads del cluster htg-nonpro consumen las mismas imágenes y Helm charts que htg-pro desde el ECR compartido 203965864736.dkr.ecr.eu-west-1.amazonaws.com, pero con un rol cross-account dedicado:
- En la cuenta CI/CD (
913305982008—aws-ac-htg-cicd) se defineecr-access-shared-htg-nonpro(móduloecr_access_htg_nonpro), cuya trust policy admite a los ServiceAccountargocd/aws-ac-htg-cicd-ecryinfra-iris-*-{dev,dev-features,test}-ecr. - Cada ServiceAccount lleva la anotación
eks.amazonaws.com/role-arnapuntando al rol cross-account. - ArgoCD lo combina con el
ECRAuthorizationTokende External Secrets para conseguir un token corto-lived sin almacenar credenciales en el cluster.
El esquema es deliberadamente idéntico al de htg-pro: aislamos por cuenta (un rol distinto por cluster) pero compartimos el patrón.