Initial commit: Terraform infrastructure, pipelines, docs and scripts

This commit is contained in:
Evert Daniel Romero Garrido
2026-04-14 14:53:05 -06:00
commit 85297b12a2
31 changed files with 4015 additions and 0 deletions
+56
View File
@@ -0,0 +1,56 @@
# 01 - ¿Qué es proyectosacc?
> Guía básica para entender el proyecto `proyectosacc` de Cómputo Contable Soft.
---
## 1. ¿Qué es este proyecto?
**proyectosacc** es el sistema de despliegue automático para la aplicación **SACC** (Sistema de Administración Contable y Comercial) de Cómputo Contable Soft.
En palabras simples: es el "puente" que lleva el código de los programadores desde **Bitbucket** hasta el servidor de AWS donde los usuarios pueden usarlo.
El proyecto tiene tres partes principales:
1. **Infraestructura en AWS**: el servidor de la API, la base de datos, el bucket S3 para el frontend, CloudFront y el dominio.
2. **Pipeline de Bitbucket**: el proceso automático que compila y publica tanto el frontend React como la API backend.
3. **Scripts de despliegue**: los archivos que instalan la API en el servidor y suben el frontend a S3.
---
## 2. ¿Qué problema resuelve?
Antes de `proyectosacc`, desplegar la aplicación SACC era un proceso manual y lento:
- Los desarrolladores tenían que copiar archivos a mano.
- Había errores porque olvidaban pasos.
- Era difícil saber qué versión estaba corriendo en producción.
**proyectosacc** resuelve esto automatizando todo:
- Cada vez que un programador sube código a Bitbucket, el pipeline se encarga de compilar, probar y desplegar.
- Si algo falla, se envía una alerta por Telegram.
- La infraestructura se crea con **Terraform**, así que siempre es la misma y no hay "magia" escondida.
---
## 3. ¿Quién lo usa?
| Rol | Cómo interactúa con el proyecto |
|-----|--------------------------------|
| **Desarrolladores** | Suben código a Bitbucket. El pipeline hace el resto. |
| **DevOps / SysAdmin** | Configuran el pipeline, revisan logs y arreglan problemas de infraestructura. |
| **Usuarios finales** | Acceden a `https://sacc.ccsoft.mx` para usar la aplicación. No ven el pipeline, pero se benefician de que siempre hay una versión estable. |
---
## 4. Dato clave
El dominio oficial de la aplicación es:
```
https://sacc.ccsoft.mx
```
Esto significa que cuando el despliegue termina exitosamente, la aplicación está disponible en esa dirección.
---
*Siguiente: [`02-arquitectura-general.md`](02-arquitectura-general.md)*
+151
View File
@@ -0,0 +1,151 @@
# 02 - Arquitectura General
> Cómo se conectan todas las piezas de `proyectosacc`.
---
## 1. Diagrama general
Aquí tienes un diagrama en texto que muestra el flujo completo:
```
┌─────────────────────────────────────────────────────────────────────────┐
│ INTERNET (usuarios) │
│ ▼ │
│ https://sacc.ccsoft.mx │
└─────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────┐
│ AWS Route 53 │
│ (traduce el dominio al destino correcto) │
└─────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────┐
│ AWS CloudFront + ACM (SSL) │
│ (distribuye el frontend globalmente y pone el candadito verde HTTPS) │
└─────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────┐
│ S3 Static Website Hosting │
│ (almacena y sirve el frontend React compilado) │
└─────────────────────────────────────────────────────────────────────────┘
FLUJO DE LA API (desde el navegador o la app)
=============================================
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Navegador/app │─────▶│ EC2 T3.small │─────▶│ RDS MariaDB │
│ (llama a /api) │ │ (API backend) │ │ (base de datos)│
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ Nginx Proxy (solo API, puerto 8080)
Servicio systemd
(usuario osiris)
OTRO FLUJO: El pipeline de despliegue
=====================================
┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Bitbucket │────▶│ Pipeline │────▶│ S3 Buckets │────▶│ EC2 T3 │
│ (código) │ │ (7 pasos) │ │ (frontend + │ │ (API) │
│ │ │ │ │ artefactos) │ │ │
└──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘
│ ▲
│ │
▼ │
CloudFront invalidation │
(actualiza cache global) │
```
---
## 2. Explicación de cada pieza
> 💡 **Dato clave**: aunque CloudFront sirve principalmente el frontend desde S3, también tiene una regla especial (`/api/*`) que envía las peticiones de la API directamente a la EC2. Así todo el tráfico de `sacc.ccsoft.mx` pasa por un solo punto.
### 🔷 Bitbucket
Es el "banco" donde se guarda el código fuente de SACC.
- Los desarrolladores suben sus cambios aquí.
- Cuando hay un cambio nuevo, Bitbucket "despierta" el pipeline.
### 🔷 Pipeline de Bitbucket (7 pasos)
Es el robot que hace todo el trabajo:
1. Prepara la imagen de compilación.
2. Descarga los repositorios.
3. Instala dependencias.
4. **Compila el frontend React (`npm run build`) y la API backend (`./gradlew bootJar`).**
5. **Sube el frontend al bucket S3 y el artefacto de la API a S3.**
6. Se conecta por SSH al servidor EC2 para desplegar la API.
7. **Invalida la caché de CloudFront, reinicia la API y verifica que todo esté saludable.**
### 🔷 S3 Bucket
Es un "almacén" de AWS con dos trabajos en `proyectosacc`:
1. **Sirve el frontend React** como un sitio web estático.
2. **Guarda los artefactos** de la API generados por el pipeline.
- También sirve como respaldo de versiones anteriores.
### 🔷 CloudFront
Es la red de distribución de contenido (CDN) de AWS.
- **Rol**: Toma los archivos del frontend desde S3 y los distribuye por todo el mundo de forma rápida y segura.
- También maneja el HTTPS con el certificado de ACM.
### 🔷 EC2 T3.small
Es el servidor virtual de AWS donde **solo vive la API/backend**.
- **Tipo**: `t3.small` (2 vCPU, 2 GB RAM).
- **Sistema operativo**: Ubuntu 22.04 LTS.
- **Rol**: Ejecuta el servicio de la API (Java) en el puerto `8080`.
- Nginx en la EC2 solo actúa como proxy hacia la API, **no sirve el frontend React**.
### 🔷 RDS MariaDB
Es la base de datos gestionada por AWS.
- **Tipo**: `db.t3.micro`.
- **Rol**: Guarda toda la información de la aplicación (clientes, facturas, usuarios, etc.).
- La EC2 se conecta a ella por la red interna de AWS.
### 🔷 Route 53
Es el servicio de DNS de AWS.
- **Rol**: Cuando un usuario escribe `sacc.ccsoft.mx`, Route 53 le dice al navegador que debe ir a **CloudFront** (no directamente a la EC2).
- Es como la "guía telefónica" de internet.
### 🔷 ACM (AWS Certificate Manager)
Es el servicio que gestiona los certificados SSL.
- **Rol**: Permite que `https://sacc.ccsoft.mx` funcione con el candadito verde.
- El certificado se adjunta a **CloudFront**, no a Nginx en la EC2.
---
## 3. Integración con proyectos CI/CD compartidos
`proyectosacc` se conecta con otros repositorios de CI/CD de Cómputo Contable Soft que le prestan "herramientas y ladrillos" ya hechos:
- **`ci-cd-commons`**: scripts base, utilerías como `telegram_alert.sh` y `logger_bash.sh`, y buenas prácticas de pipeline.
- **`ci-cd-saac4`**: módulos de Terraform, patrones de infraestructura AWS y scripts de despliegue adaptados para la familia de aplicaciones SACC.
Esto evita reinventar la rueda en cada proyecto y mantiene todo alineado con los estándares de la empresa.
---
## 4. ¿Por qué cada pieza existe?
| Pieza | ¿Por qué la necesitamos? |
|-------|--------------------------|
| Bitbucket | Para guardar el código y activar el pipeline automáticamente. |
| Pipeline | Para que nadie tenga que copiar archivos a mano. |
| S3 | Para servir el frontend React y guardar los artefactos de la API de forma segura. |
| CloudFront | Para distribuir el frontend rápidamente por todo el mundo con HTTPS. |
| EC2 T3 | Es el servidor donde corre la API backend. Sin él, no hay dónde procesar las peticiones de datos. |
| RDS | Es mejor que instalar la base de datos en la misma EC2 porque AWS la respalda, actualiza y monitorea automáticamente. |
| Route 53 | Para que los usuarios no tengan que memorizar una IP numérica. |
| ACM | Para que la conexión sea segura (HTTPS) y proteger los datos de los usuarios. |
| Nginx | Para recibir las peticiones a la API y pasarlas al servicio backend en el puerto 8080. |
---
*Anterior: [`01-que-es-proyectosacc.md`](01-que-es-proyectosacc.md)*
*Siguiente: [`03-infraestructura-aws.md`](03-infraestructura-aws.md)*
+167
View File
@@ -0,0 +1,167 @@
# 03 - Infraestructura AWS
> Descripción detallada de cada recurso de AWS que usa `proyectosacc`.
---
## 1. EC2 T3.small
La **EC2** (Elastic Compute Cloud) es el servidor virtual donde corre la aplicación SACC.
### Especificaciones
- **Tipo de instancia**: `t3.small`
- **vCPU**: 2
- **RAM**: 2 GB
- **Sistema operativo**: Ubuntu 22.04 LTS
- **Disco raíz**: 20 GB SSD (`gp3`), con cifrado obligatorio
### ¿Qué hace?
- **Ejecuta la API/backend de SACC** como un servicio de `systemd` (puerto `8080`).
- Corre **Nginx Proxy** solo para redirigir las peticiones de la API hacia el backend.
- **NO sirve el frontend React** (eso lo hace S3 + CloudFront).
- Se conecta a la base de datos RDS para leer y guardar datos.
- **Solo acepta conexiones SSH con llaves dedicadas**: el pipeline y los administradores usan un par de llaves SSH generado específicamente para `proyectosacc`. No se permite acceso con contraseña.
### Dato importante
En Cómputo Contable Soft hay una regla obligatoria: **todas las instancias EC2 deben ser de la familia T3**. Esto garantiza el mejor balance entre costo y rendimiento.
---
## 2. RDS MariaDB
La **RDS** (Relational Database Service) es la base de datos gestionada por AWS.
### Especificaciones
- **Motor**: MariaDB
- **Tipo de instancia**: `db.t3.micro`
- **vCPU**: 2
- **RAM**: 1 GB
- **Uso**: Base de datos de la aplicación SACC
### ¿Qué hace?
- Guarda todos los datos de la aplicación: usuarios, clientes, productos, facturas, etc.
- AWS se encarga de hacer respaldos automáticos, aplicar parches de seguridad y monitorear el rendimiento.
### Ventaja principal
No tenemos que instalar ni mantener MariaDB nosotros mismos en el servidor. AWS lo hace por nosotros.
---
## 3. S3 Bucket
El **S3** (Simple Storage Service) es el almacén de archivos de AWS.
### ¿Qué guardamos aquí?
1. **El frontend React compilado** (`build/`) como un sitio web estático. CloudFront lee estos archivos para servirlos a los usuarios.
2. Los archivos compilados (artefactos `.jar`) de la API backend.
3. Versiones anteriores por si necesitamos hacer un *rollback*.
4. Logs y respaldos temporales.
### Ejemplo de rutas dentro del bucket
```
s3://ccsoft-proyectosacc-frontend/index.html
s3://ccsoft-artifacts-sacc4/develop/proyectosacc-app-1.0.0.jar
```
### ¿Por qué S3?
- Es muy económico.
- Es duradero (AWS garantiza que no se pierdan los archivos).
- El pipeline puede subir y descargar archivos fácilmente.
---
## 4. CloudFront
**CloudFront** es la red de distribución de contenido (CDN) de AWS.
### ¿Qué hace?
- Distribuye el frontend React desde el bucket S3 a los usuarios de todo el mundo.
- Reduce la latencia porque los archivos se sirven desde el "edge location" más cercano al usuario.
- Termina el cifrado SSL/TLS (HTTPS) usando el certificado de ACM.
- Se conecta a S3 mediante **Origin Access Control (OAC)** para que el bucket no sea público directamente.
### Relación con S3 y la API
CloudFront lee los archivos estáticos (`index.html`, CSS, JS) desde S3. Además, tiene un behavior `/api/*` que redirige las peticiones de la API hacia la EC2. De esta forma, tanto el frontend como el backend comparten el mismo dominio `https://sacc.ccsoft.mx`, pero los usuarios nunca acceden directamente al bucket S3.
---
## 5. Route 53
**Route 53** es el servicio de DNS de AWS.
### Registro configurado
- **Nombre**: `sacc.ccsoft.mx`
- **Tipo**: A (Alias)
- **Destino**: **CloudFront Distribution** (no la IP de la EC2)
### ¿Qué hace?
Cuando un usuario escribe `https://sacc.ccsoft.mx` en su navegador, Route 53 le dice: "ve a CloudFront". Sin Route 53, los usuarios tendrían que escribir una URL larga de CloudFront.
---
## 6. ACM (AWS Certificate Manager)
**ACM** es el servicio que gestiona certificados SSL/TLS.
### ¿Qué es un certificado SSL?
Es un documento digital que permite que la conexión entre el usuario y el servidor esté cifrada. Se ve como el candadito verde 🔒 al lado de la dirección web.
### ¿Cómo lo usamos?
1. Solicitamos un certificado en ACM para el dominio `sacc.ccsoft.mx`.
2. ACM valida que el dominio nos pertenece.
3. El certificado se adjunta a la **distribución de CloudFront**.
4. Los usuarios acceden por **HTTPS** de forma segura. El certificado ya no vive en Nginx de la EC2.
---
## 7. Security Groups
Un **Security Group** es como un "guardia de seguridad" virtual que controla quién puede entrar y salir de la EC2.
### Reglas de entrada (inbound)
| Puerto | Origen | ¿Para qué? |
|--------|--------|-----------|
| `22` | IP del pipeline / VPN | Conexión SSH para despliegues de la API |
| `80` | `0.0.0.0/0` (todo internet) | Tráfico HTTP hacia la API (puede redirigir a HTTPS) |
| `443` | `0.0.0.0/0` (todo internet) | Tráfico HTTPS hacia la API |
| `8080` | IPs de la VPC / CloudFront | Acceso directo a la API backend |
> 💡 **Nota**: los puertos `80` y `443` en la EC2 ya no sirven el frontend React. Solo reciben peticiones a la API. El frontend se sirve desde CloudFront.
### Reglas de salida (outbound)
| Puerto | Destino | ¿Para qué? |
|--------|---------|-----------|
| Todo (`0-65535`) | `0.0.0.0/0` | La EC2 puede salir a internet (descargar paquetes, consultar APIs, etc.) |
### Regla de seguridad importante
El puerto `22` (SSH) **solo debe abrirse desde IPs confiables**. Nunca dejarlo abierto a todo el mundo (`0.0.0.0/0`).
---
## 8. Nginx Proxy en la EC2
**Nginx** es un servidor web que en este proyecto actúa como **proxy inverso exclusivo para la API**.
### ¿Qué hace Nginx?
1. Escucha en los puertos `80` y/o `443`.
2. Recibe las peticiones dirigidas a la API (por ejemplo, `sacc.ccsoft.mx/api`).
3. Redirige el tráfico al backend que corre en el puerto interno `8080`.
4. **NO sirve archivos estáticos del frontend React** (eso es trabajo de S3 + CloudFront).
### Ejemplo mental simple
```
Navegador/app ──▶ Nginx (443) ──▶ API SACC (8080)
```
### ¿Por qué Nginx y no Apache?
En `proyectosacc` se decidió usar **Nginx** porque:
- Consume menos memoria RAM.
- Es más rápido manejando muchas conexiones simultáneas.
- La configuración de proxy inverso es más sencilla.
---
*Anterior: [`02-arquitectura-general.md`](02-arquitectura-general.md)*
*Siguiente: [`04-usuarios-y-permisos.md`](04-usuarios-y-permisos.md)*
+134
View File
@@ -0,0 +1,134 @@
# 04 - Usuarios y Permisos
> Quién puede hacer qué en el servidor de `proyectosacc`.
---
## 1. Usuarios del sistema
En el servidor EC2 de `proyectosacc` existen tres usuarios principales. Cada uno tiene un trabajo específico y **no se mezclan los roles**.
---
### 👤 `ubuntu`
Este es el usuario administrador por defecto de Ubuntu en AWS.
#### ¿Qué puede hacer?
- Todo. Es el usuario con permisos de `sudo` (superusuario).
- Se usa para configurar el servidor por primera vez.
- Puede instalar programas, crear otros usuarios y revisar logs del sistema.
#### ¿Cuándo se usa?
- Durante el setup inicial del servidor.
- Para tareas de mantenimiento que requieren privilegios elevados.
- **No se usa para despliegues automáticos ni para ejecutar la aplicación.**
---
### 👤 `thoth`
Este es el usuario de **CI/CD** (Integración Continua / Despliegue Continuo).
#### ¿Qué puede hacer?
- ✅ Descargar actualizaciones de los repositorios de código (solo lectura).
- ✅ Subir el frontend compilado al bucket S3 (`aws s3 sync`).
- ✅ Mover archivos compilados de la API (binarios, JARs, etc.) a los directorios correctos en la EC2.
- ✅ Hacer copias de seguridad (backups) de los binarios antes de actualizarlos.
- ✅ Ejecutar los scripts de despliegue de la API.
#### ¿Qué NO puede hacer?
- ❌ Ejecutar la aplicación final en producción. Ese trabajo es de `osiris`.
#### ¿Por qué existe?
Para que el pipeline de Bitbucket se conecte por SSH al servidor y haga el despliegue sin necesidad de usar el usuario administrador.
---
### 👤 `osiris`
Este es el usuario de **ejecución** de la aplicación.
#### ¿Qué puede hacer?
- ✅ Iniciar y detener la aplicación SACC.
- ✅ Ejecutar los binarios finales (por ejemplo, archivos `.jar` de Java).
- ✅ Escribir logs en los directorios asignados.
#### ¿Qué NO puede hacer?
- ❌ Realizar despliegues.
- ❌ Mover archivos de instalación.
- ❌ Acceder a repositorios de código.
#### ¿Por qué existe?
Por seguridad. Si alguien compromete la aplicación, el atacante solo tendría los permisos de `osiris`, que son muy limitados.
---
## 2. Separación de privilegios
Este modelo se llama **SoD** (Segregation of Duties) o "Separación de Funciones".
La idea es simple: **una sola persona (o usuario) no debe poder hacer todo**.
```
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ thoth │ │ osiris │ │ ubuntu │
│ (CI/CD) │ │ (ejecución) │ │ (admin) │
│ │ │ │ │ │
│ Despliega │ ──▶ │ Ejecuta │ ◀── │ Administra │
│ la app │ │ la app │ │ el server │
└─────────────┘ └─────────────┘ └─────────────┘
```
---
## 3. Llaves SSH
Las **llaves SSH** son como un "carnet de identidad digital" que permite conectarse al servidor sin escribir una contraseña cada vez.
En `proyectosacc` usamos un **par de llaves SSH dedicado**, generado específicamente para este proyecto. No se usa contraseña ni herramientas como `sshpass`.
### ¿Cómo funcionan?
Una llave SSH siempre viene en **par**:
1. **Llave privada**: es secreta. Solo la tiene quien se va a conectar.
2. **Llave pública**: se puede compartir. Se coloca en el servidor para decirle "confía en quien tenga la llave privada que corresponde a esta pública".
### Analogía simple
Imagina un candado con dos llaves:
- La **pública** es el candado mismo. Lo pones en la puerta del servidor.
- La **privada** es la llave que abre el candado. Solo tú la tienes.
---
## 4. Dónde viven las llaves
### Llave privada
- **Vive en**: las variables seguras de **Bitbucket Pipelines**.
- **Nombre de variable**: `PROYECTOSACC_SSH_KEY`
- **Formato**: codificada en **base64** (esto evita que Bitbucket modifique el formato).
- **Quién la usa**: el pipeline de Bitbucket cuando se conecta por SSH al servidor.
### Llave pública
- **Vive en**: el archivo `~/.ssh/authorized_keys` del usuario `thoth` en la EC2.
- **Ruta completa**: `/home/thoth/.ssh/authorized_keys`
- **Función**: permite que el pipeline se conecte sin contraseña.
### Llaves del servidor hacia Bitbucket
- El usuario `thoth` también tiene sus propias llaves SSH para clonar repositorios desde Bitbucket.
- **Ubicación**: `/home/thoth/.ssh/`
- **Ejemplo de nombre**: `proyectosacc_server_thoth_develop_TO_bitbucket_pipeline_ci_cd`
---
## 5. Resumen rápido
| Usuario | Rol principal | Llave SSH asociada |
|---------|---------------|-------------------|
| `ubuntu` | Administrador del servidor | Llave de acceso inicial a la EC2 (creada al lanzarla en AWS) |
| `thoth` | Despliegue automático (CI/CD) | `PROYECTOSACC_SSH_KEY` en Bitbucket Variables |
| `osiris` | Ejecutar la aplicación | No necesita llave SSH para conexiones externas |
---
*Anterior: [`03-infraestructura-aws.md`](03-infraestructura-aws.md)*
*Siguiente: [`05-pipeline-bitbucket.md`](05-pipeline-bitbucket.md)*
+199
View File
@@ -0,0 +1,199 @@
# 05 - Pipeline Bitbucket
> Cómo funciona el pipeline de 7 pasos que despliega `proyectosacc`.
---
## 1. ¿Qué es un pipeline?
Un **pipeline** es una serie de pasos automáticos que se ejecutan cada vez que alguien sube código al repositorio.
En Cómputo Contable Soft, todos los pipelines web usan **7 pasos** estandarizados. Esto significa que, sin importar el proyecto, siempre hay los mismos pasos con los mismos nombres.
---
## 2. Los 7 pasos del pipeline
### Paso 1: `01_image-setup`
**Prepara la computadora virtual donde se va a compilar todo.**
Qué hace:
1. Actualiza los paquetes del sistema.
2. Instala herramientas necesarias: `openssh-client`, `openjdk-21-jdk`, `aws-cli`.
3. Configura las llaves SSH y los `known_hosts`.
4. Carga los scripts de utilería (`logger_bash.sh`, `telegram_alert.sh`).
> 💡 **En palabras simples**: como cuando llegas a una cocina nueva y primero lavas los trastes, prendes la estufa y sacas los utensilios.
---
### Paso 2: `02_repo-config`
**Descarga todos los repositorios que necesita la aplicación.**
Qué hace:
1. Clona el repositorio principal de la aplicación.
2. Clona los repositorios de componentes compartidos (por ejemplo, `cmp-commons`, `cmp-security`).
3. Clona `ci-cd-commons` (scripts base de CCsoft).
> 💡 **En palabras simples**: bajas todos los ingredientes de la receta antes de empezar a cocinar.
---
### Paso 3: `03_dependencies`
**Compila o descarga todo lo que la aplicación necesita para funcionar.**
Qué hace:
1. Compila las librerías compartidas.
2. Descarga dependencias de Maven, Gradle, npm, etc.
3. Publica las librerías locales si es necesario.
> 💡 **En palabras simples**: preparas la masa, cortas las verduras y sacas los condimentos antes de armar el platillo final.
---
### Paso 4: `04_build`
**Compila el frontend React y la API backend.**
Qué hace:
1. **Frontend**: ejecuta `npm run build` (o `npm ci && npm run build`) para generar la carpeta `build/` con el React estático.
2. **Backend**: ejecuta el comando de build de la API (por ejemplo, `./gradlew clean bootJar` para Java).
3. Genera los archivos finales: la carpeta `build/` para el frontend y el `.jar` para la API.
> 💡 **En palabras simples**: aquí cocinamos dos platillos: la entrada (frontend) y el plato fuerte (API).
---
### Paso 5: `05_publish`
**Sube el frontend a S3 y el artefacto de la API a Amazon S3.**
Qué hace:
1. **Frontend**: sincroniza la carpeta `build/` al bucket S3 designado para el sitio estático (`aws s3 sync build/ s3://bucket-name`).
2. **Backend**: sube el `.jar` (o artefacto equivalente) al bucket S3 para que la EC2 lo descargue después.
3. Esto evita transferir archivos grandes directamente por SSH y permite recuperar versiones anteriores fácilmente.
> 💡 **En palabras simples**: pones la entrada en el mostrador (S3) y el plato fuerte en la bandeja de la cocina (S3) para servirlo después.
---
### Paso 6: `06_install`
**Descarga el artefacto de la API en el servidor EC2.**
Qué hace:
1. Se conecta por SSH al servidor EC2 como `thoth`.
2. Ejecuta un script de preparación que descarga el `.jar` desde **S3** y lo coloca en `/home/thoth/deploy/artifacts/current/`.
3. También hace una copia de seguridad de la versión anterior.
4. **Aún no reinicia el servicio**: eso ocurre en el paso 7.
> 💡 **En palabras simples**: pones el plato fuerte en el plato y lo dejas listo, pero aún no lo sirves.
---
### Paso 7: `07_deploy`
**Invalida la caché de CloudFront, despliega la API y verifica que todo esté saludable.**
Qué hace:
1. **Invalida la caché de CloudFront** (`aws cloudfront create-invalidation`) para que los usuarios vean la nueva versión del frontend inmediatamente.
2. Se conecta por SSH al servidor EC2 como `thoth` y ejecuta `bash /home/thoth/deploy/setup/deploy.sh`.
3. El script `deploy.sh` crea o actualiza el servicio de `systemd`, detiene la versión anterior e inicia la nueva con el usuario `osiris`.
4. Ejecuta un **health check** en la API para verificar que responde correctamente.
5. Envía una notificación por Telegram con el resultado.
> 💡 **En palabras simples**: actualizas el menú en todos los restaurantes (CloudFront) y sirves el plato fuerte calentito desde la cocina (EC2).
---
## 3. Diagrama del pipeline
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ BITBUCKET PIPELINE │
│ │
│ 1. image-setup ▶ Instala herramientas │
│ │ │
│ ▼ │
│ 2. repo-config ▶ Descarga repositorios │
│ │ │
│ ▼ │
│ 3. dependencies ▶ Compila librerías y dependencias │
│ │ │
│ ▼ │
│ 4. build ▶ Compila React frontend + API backend (.jar) │
│ │ │
│ ▼ │
│ 5. publish ▶ Sube frontend a S3 web + API .jar a S3 artifacts │
│ │ │
│ ▼ │
│ 6. install ▶ Prepara la API en el servidor EC2 │
│ │ │
│ ▼ │
│ 7. deploy ▶ Invalida CloudFront, reinicia API y health check │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
```
---
## 4. ¿Cómo se conecta el pipeline a la EC2?
La conexión se hace por **SSH** (Secure Shell).
1. El pipeline tiene guardada la **llave privada** de `thoth` en una variable segura de Bitbucket.
2. Al llegar al paso `05_publish` o `06_install`, el pipeline decodifica la llave y la guarda en `/root/.ssh/sacc4_key`.
3. Ejecuta un comando `ssh` usando esa llave para ejecutar scripts remotos.
4. La **llave pública** correspondiente ya está en el archivo `~/.ssh/authorized_keys` del usuario `thoth` en la EC2.
5. ¡La puerta se abre y el pipeline puede ejecutar comandos en el servidor!
### Ejemplo del comando que usa el pipeline
```bash
ssh -p 22 \
-i /root/.ssh/sacc4_key \
-o StrictHostKeyChecking=no \
thoth@<IP_DE_LA_EC2> \
"bash /home/thoth/deploy/setup/deploy.sh"
```
---
## 5. ¿De dónde salen los secrets?
Los **secrets** (contraseñas, llaves, tokens) viven en las **variables de repositorio** de Bitbucket.
### Cómo se configuran
1. Entra al repositorio en Bitbucket.
2. Ve a **Repository settings > Pipelines > Repository variables**.
3. Agrega cada variable y márcala como **Secured** 🔒.
4. Las variables marcadas como secured se ofuscan en los logs (aparecen como `***`).
### Variables principales
| Variable | Descripción |
|----------|-------------|
| `PROYECTOSACC_SSH_KEY` | Llave privada SSH (en base64) dedicada para conectar al servidor |
| `PROYECTOSACC_SERVER_IP` | IP pública de la EC2 |
| `PROYECTOSACC_SSH_PORT` | Puerto SSH (normalmente `22`) |
| `PROYECTOSACC_SERVER_USER` | Usuario SSH para despliegue (`thoth`) |
| `PROYECTOSACC_TELEGRAM_BOT_TOKEN` | Token del bot de Telegram para alertas |
| `PROYECTOSACC_TELEGRAM_CHAT_ID` | ID del chat donde llegan las alertas |
| `AWS_ACCESS_KEY_ID` | Credencial de AWS para subir a S3 |
| `AWS_SECRET_ACCESS_KEY` | Credencial secreta de AWS |
| `CLOUDFRONT_DISTRIBUTION_ID` | ID de la distribución de CloudFront para invalidaciones |
| `S3_FRONTEND_BUCKET` | Nombre del bucket S3 donde se publica el frontend |
### ⚠️ Regla de oro
**NUNCA** escribas secrets directamente en el código del pipeline (`bitbucket-pipelines.yml`). Siempre usa variables de entorno.
---
## 6. Integración con proyectos CI/CD compartidos
`proyectosacc` no trabaja solo. Se conecta con otros proyectos de CI/CD de la empresa que proveen piezas reutilizables:
- **`ci-cd-commons`**: scripts base compartidos como `telegram_alert.sh` y `logger_bash.sh`.
- **`ci-cd-saac4`**: módulos de Terraform, patrones de infraestructura y scripts de despliegue específicos para la familia SACC.
Esto significa que parte del pipeline y de los scripts de despliegue vienen de esos repositorios, no de este. Es como armar una casa con ladrillos que ya están hechos en otra fábrica.
---
*Anterior: [`04-usuarios-y-permisos.md`](04-usuarios-y-permisos.md)*
*Siguiente: [`06-scripts-de-despliegue.md`](06-scripts-de-despliegue.md)*
+197
View File
@@ -0,0 +1,197 @@
# 06 - Scripts de Despliegue
> Qué hace cada script y cuándo se ejecuta.
---
## 1. ¿Qué son los scripts de despliegue?
Los **scripts** son archivos de texto con instrucciones que la computadora puede ejecutar automáticamente.
En `proyectosacc` usamos scripts escritos en **Bash** (el lenguaje de comandos de Linux). Todos comienzan con esta línea mágica:
```bash
set -euo pipefail
```
Esto significa tres cosas:
1. **`set -e`**: Si un comando falla, el script se detiene inmediatamente.
2. **`set -u`**: Si usas una variable que no existe, el script se detiene.
3. **`set -o pipefail`**: Si un comando dentro de una "tubería" (`|`) falla, el script también se detiene.
> 💡 **En palabras simples**: es como poner el cinturón de seguridad antes de manejar.
---
### 1.1. Scripts provenientes de otros proyectos CI/CD
`proyectosacc` reutiliza scripts y utilerías que viven en repositorios compartidos:
- **`ci-cd-commons`**: contiene `telegram_alert.sh`, `logger_bash.sh` y otras utilerías base que usan todos los pipelines de la empresa.
- **`ci-cd-saac4`**: provee módulos de Terraform y scripts de despliegue adaptados para la familia SACC.
Estos repositorios se clonan dentro de la carpeta `/home/thoth/deploy/` (por ejemplo, `/home/thoth/deploy/ci-cd-commons/`) para que los scripts locales puedan usarlos.
### 1.2. Nuevo script: `deploy-frontend-s3.sh`
Este script se ejecuta **desde el pipeline de Bitbucket** (no dentro de la EC2). Su trabajo es subir el frontend React a S3.
Qué hace:
1. Sincroniza la carpeta `build/` con el bucket S3 (`aws s3 sync build/ s3://bucket-name --delete`).
2. Espera a que la sincronización termine.
> 💡 **Nota**: la invalidación de la caché de CloudFront se hace en el **paso 7** del pipeline (`07_deploy`), después de confirmar que la API está saludable. Así evitamos refrescar el frontend antes de que el backend esté listo.
Ejemplo de comando:
```bash
bash /home/thoth/deploy/scripts/deploy-frontend-s3.sh
```
---
## 2. `deploy.sh`
### ¿Qué hace?
Este es el script principal de despliegue de la **API backend**. Se ejecuta **dentro del servidor EC2** y se encarga de instalar la nueva versión del servicio.
### Pasos que sigue
1. **Crear directorios**: verifica que existan las carpetas necesarias (`backup`, `current`, `pids`, `logs`).
2. **Detener servicio anterior**: si la aplicación ya está corriendo, la detiene con `systemctl`.
3. **Configurar systemd**: crea o actualiza el archivo de servicio para que la app inicie automáticamente.
4. **Recargar systemd**: ejecuta `sudo systemctl daemon-reload`.
5. **Iniciar servicio**: ejecuta `sudo systemctl start <nombre-del-servicio>`.
6. **Health check**: hace peticiones a `http://localhost:8080/actuator/health` para verificar que la app responde.
7. **Guardar PID**: anota el ID del proceso para poder monitorearlo después.
### ¿Cuándo se llama?
- En el **paso 7** del pipeline (`07_deploy`).
- También puede ejecutarse manualmente si necesitas hacer un despliegue fuera del pipeline.
### Ejemplo de comando
```bash
bash /home/thoth/deploy/setup/deploy.sh
```
---
## 3. `health-check.sh`
### ¿Qué hace?
Verifica que la aplicación esté viva y respondiendo correctamente.
### Cómo funciona
1. Intenta conectarse a la URL de salud de la aplicación:
```
http://localhost:8080/actuator/health
```
2. Si la respuesta contiene `"status":"UP"`, todo está bien.
3. Si no responde después de varios intentos, reporta un error.
### ¿Cuándo se llama?
- **Dentro de `deploy.sh`**, inmediatamente después de iniciar el servicio.
- También puede usarse manualmente para revisar si la app sigue funcionando horas después del despliegue.
### Ejemplo de comando manual
```bash
bash /home/thoth/deploy/scripts/health-check.sh
```
---
## 4. `rollback.sh`
### ¿Qué hace?
Regresa la API backend a la versión anterior si el nuevo despliegue falló. También puede restaurar el frontend en S3 si se habilitó **versionamiento de objetos** en el bucket.
### Pasos que sigue (API en EC2)
1. Busca el último backup en la carpeta `/home/thoth/deploy/artifacts/backup/`.
2. Detiene el servicio actual.
3. Copia el backup a la carpeta `current`.
4. Reinicia el servicio con la versión anterior.
5. Ejecuta un health check para confirmar que la versión anterior todavía funciona.
### Pasos que sigue (frontend en S3)
Si el frontend también necesita rollback:
1. Identifica la versión anterior del archivo en S3 usando el versionamiento del bucket.
2. Restaura la versión anterior de `index.html` y los assets estáticos.
3. Invalida la caché de CloudFront para que los usuarios vean la versión anterior.
### ¿Cuándo se llama?
- Cuando el `deploy.sh` o el `health-check.sh` reportan un fallo en la API.
- Manualmente, si descubres que la nueva versión del frontend o la API tiene un bug grave.
### Ejemplo de comando
```bash
bash /home/thoth/deploy/scripts/rollback.sh
```
---
## 5. `notify-telegram.sh`
### ¿Qué hace?
Envía mensajes a un grupo o chat de Telegram para informar sobre el estado del pipeline.
### Qué tipo de mensajes envía
- 🟢 **Éxito**: "El despliegue de proyectosacc terminó correctamente."
- 🔴 **Error**: "El pipeline de proyectosacc falló en el paso 4. Revisar logs."
- 🟡 **Advertencia**: "Health check falló. Iniciando rollback automático."
### ¿Cuándo se llama?
- Al **inicio** del pipeline.
- Al **final** del pipeline (éxito o fracaso).
- Cuando ocurre un error en cualquier paso.
### Variables necesarias
```bash
TELEGRAM_BOT_TOKEN=<token-del-bot>
TELEGRAM_CHAT_ID=<id-del-chat>
```
### Ejemplo de comando
```bash
bash /home/thoth/deploy/ci-cd-commons/telegram_alert.sh "Despliegue exitoso"
```
---
## 6. Resumen de cuándo usar cada script
| Script | ¿Cuándo se ejecuta? | ¿Dónde corre? |
|--------|---------------------|---------------|
| `deploy-frontend-s3.sh` | Paso 5 del pipeline (subir React a S3) | Pipeline (Bitbucket) |
| `deploy.sh` | Paso 7 del pipeline (desplegar API en la EC2), o manualmente | Dentro de la EC2 |
| `health-check.sh` | Después de `deploy.sh`, o manualmente | Dentro de la EC2 |
| `rollback.sh` | Cuando `deploy.sh` o `health-check.sh` fallan, o manualmente | Pipeline o EC2 |
| `notify-telegram.sh` | Inicio, fin o error del pipeline | Pipeline (Bitbucket) o EC2 |
---
## 7. Dato extra: ¿dónde viven los scripts?
En el servidor EC2, los scripts se organizan así:
```
/home/thoth/deploy/
├── artifacts/
│ ├── backup/ ← versiones anteriores de la API
│ ├── current/ ← versión activa de la API
│ ├── logs/ ← logs del pipeline
│ └── pids/ ← archivos con el ID de proceso
├── ci-cd-commons/
│ ├── telegram_alert.sh
│ └── logger_bash.sh
├── scripts/
│ ├── deploy-frontend-s3.sh ← sube React a S3
│ ├── health-check.sh
│ └── rollback.sh
└── setup/
└── deploy.sh ← script principal del pipeline para la API (llamado vía SSH)
```
> 💡 **Nota**: el artefacto de la API que termina en `artifacts/current/` se descarga desde **Amazon S3** durante el paso de instalación del pipeline. No se transfiere directamente por SSH. El frontend React se sube directamente a S3 desde el pipeline.
---
*Anterior: [`05-pipeline-bitbucket.md`](05-pipeline-bitbucket.md)*
*Siguiente: [`07-terraform-iac.md`](07-terraform-iac.md)*
+322
View File
@@ -0,0 +1,322 @@
# 07 - Terraform (IaC)
> Cómo creamos la infraestructura de `proyectosacc` con código.
---
## 1. ¿Qué es Terraform?
**Terraform** es una herramienta que permite crear infraestructura en la nube escribiendo código en lugar de hacer clic en la consola de AWS.
A esto se le llama **IaC** (Infrastructure as Code) o "Infraestructura como Código".
### Ventajas de usar Terraform
-**Repetible**: puedes crear la misma infraestructura 10 veces y siempre será idéntica.
-**Versionable**: el código se guarda en Git, así que sabes quién hizo qué cambio y cuándo.
-**Rápido**: un solo comando crea servidor, base de datos, DNS y seguridad.
-**Sin sorpresas**: todo está documentado en archivos de texto.
---
## 2. ¿Qué crea Terraform en proyectosacc?
Terraform se encarga de crear todos estos recursos en AWS:
1. **VPC y subredes**: la red virtual donde vive todo.
2. **Security Groups**: las reglas de firewall.
3. **EC2 T3.small**: el servidor de la **API backend**.
4. **RDS MariaDB**: la base de datos gestionada.
5. **S3 Bucket (artefactos)**: el almacén de archivos de la API.
6. **S3 Bucket (frontend)**: el sitio web estático que sirve el React app.
7. **CloudFront Distribution**: la CDN que distribuye el frontend globalmente con HTTPS.
8. **Route 53 Record**: el dominio `sacc.ccsoft.mx` apunta a CloudFront.
9. **ACM Certificate**: certificado SSL para CloudFront.
10. **IAM Role**: permisos para que la EC2 y CloudFront accedan a S3.
---
## 3. Archivos principales de Terraform
### `main.tf`
Este es el archivo central. Aquí se definen los recursos que Terraform va a crear.
Ejemplo de la EC2 para la API:
```hcl
resource "aws_instance" "sacc_api" {
ami = "ami-0c02fb55956c7d316" # Ubuntu 22.04
instance_type = "t3.small"
vpc_security_group_ids = [aws_security_group.sacc_sg.id]
user_data = file("user-data.sh")
tags = {
Name = "proyectosacc-api"
Environment = "develop"
Project = "proyectosacc"
}
}
```
Ejemplo del bucket S3 para el frontend React:
```hcl
resource "aws_s3_bucket" "sacc_frontend" {
bucket = "ccsoft-proyectosacc-frontend"
}
resource "aws_s3_bucket_website_configuration" "sacc_frontend" {
bucket = aws_s3_bucket.sacc_frontend.id
index_document {
suffix = "index.html"
}
error_document {
key = "index.html"
}
}
```
Ejemplo de CloudFront:
```hcl
resource "aws_cloudfront_distribution" "sacc_cdn" {
enabled = true
default_root_object = "index.html"
aliases = ["sacc.ccsoft.mx"]
# Origin 1: S3 bucket para el frontend React
origin {
domain_name = aws_s3_bucket.sacc_frontend.bucket_regional_domain_name
origin_id = "saccS3Origin"
s3_origin_config {
origin_access_identity = aws_cloudfront_origin_access_identity.sacc_oai.cloudfront_access_identity_path
}
}
# Origin 2: EC2 para la API backend
origin {
domain_name = aws_instance.sacc_api.public_dns
origin_id = "saccApiOrigin"
custom_origin_config {
http_port = 80
https_port = 443
origin_protocol_policy = "http-only"
origin_ssl_protocols = ["TLSv1.2"]
}
}
default_cache_behavior {
target_origin_id = "saccS3Origin"
viewer_protocol_policy = "redirect-to-https"
allowed_methods = ["GET", "HEAD", "OPTIONS"]
cached_methods = ["GET", "HEAD"]
}
# API requests go to the EC2 origin
ordered_cache_behavior {
path_pattern = "/api/*"
target_origin_id = "saccApiOrigin"
allowed_methods = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
cached_methods = ["GET", "HEAD"]
viewer_protocol_policy = "redirect-to-https"
forwarded_values {
query_string = true
headers = ["Origin", "Access-Control-Request-Headers", "Access-Control-Request-Method"]
cookies {
forward = "all"
}
}
}
viewer_certificate {
acm_certificate_arn = aws_acm_certificate.sacc_cert.arn
ssl_support_method = "sni-only"
minimum_protocol_version = "TLSv1.2_2021"
}
}
```
> 💡 **¿Por qué dos origins?** CloudFront sirve el frontend desde S3 por defecto. Pero cuando el navegador pide algo bajo `/api/*`, CloudFront lo envía a la EC2 donde Nginx lo redirige al backend en el puerto 8080. Así todo comparte el mismo dominio `sacc.ccsoft.mx`.
---
### `variables.tf`
Aquí se definen las variables que personalizan la infraestructura.
Ejemplo:
```hcl
variable "region" {
description = "Región de AWS"
type = string
default = "us-east-1"
}
variable "instance_type" {
description = "Tipo de instancia EC2"
type = string
default = "t3.small"
}
variable "db_password" {
description = "Contraseña de la base de datos"
type = string
sensitive = true
}
```
> ⚠️ La variable `db_password` tiene `sensitive = true` para que no aparezca en los logs.
---
### `user-data.sh`
Este archivo contiene los comandos que la EC2 ejecuta la **primera vez** que se enciende.
Ejemplo de lo que hace:
1. Actualiza el sistema operativo.
2. Instala Nginx.
3. Instala Java (para correr la aplicación SACC).
4. Instala AWS CLI.
5. Crea los usuarios `thoth` y `osiris`.
6. Inyecta la **llave pública SSH dedicada** para el pipeline en `~/.ssh/authorized_keys` del usuario `thoth`.
7. Crea los directorios necesarios para el despliegue.
```bash
#!/bin/bash
set -euo pipefail
# Actualizar sistema
apt-get update -y
apt-get install -y nginx openjdk-21-jdk awscli
# Crear usuarios
useradd -m -s /bin/bash thoth || true
useradd -m -s /bin/bash osiris || true
# Crear directorios de despliegue
mkdir -p /home/thoth/deploy/artifacts/{backup,current,logs,pids}
chown -R thoth:thoth /home/thoth/deploy
# Configurar Nginx como proxy SOLO para la API (no para el frontend)
cat > /etc/nginx/sites-available/proyectosacc-api <<'EOF'
server {
listen 80;
server_name _;
location /api/ {
proxy_pass http://localhost:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
EOF
ln -sf /etc/nginx/sites-available/proyectosacc-api /etc/nginx/sites-enabled/default
# Iniciar Nginx
systemctl enable nginx
systemctl start nginx
```
---
### `outputs.tf`
Aquí definimos qué información queremos que Terraform nos muestre al final.
Ejemplo:
```hcl
output "ec2_public_ip" {
description = "IP pública del servidor de la API"
value = aws_instance.sacc_api.public_ip
}
output "rds_endpoint" {
description = "Dirección de conexión a la base de datos"
value = aws_db_instance.sacc_db.endpoint
}
output "s3_artifacts_bucket" {
description = "Nombre del bucket de artefactos de la API"
value = aws_s3_bucket.artifacts.bucket
}
output "s3_frontend_bucket" {
description = "Nombre del bucket del frontend React"
value = aws_s3_bucket.sacc_frontend.bucket
}
output "cloudfront_domain" {
description = "Dominio de CloudFront"
value = aws_cloudfront_distribution.sacc_cdn.domain_name
}
```
Después de ejecutar `terraform apply`, verás estos valores en la pantalla.
---
## 4. Cómo ejecutar Terraform paso a paso
### Paso 1: Ir a la carpeta de Terraform
```bash
cd /home/evert/Servidores/Nuve/AWS/proyectosacc/terraform
```
### Paso 2: Inicializar Terraform
```bash
terraform init
```
Esto descarga los plugins necesarios para hablar con AWS.
### Paso 3: Revisar el plan
```bash
terraform plan
```
Terraform te muestra **todo lo que va a crear, modificar o destruir**. Revísalo con cuidado.
### Paso 4: Aplicar los cambios
```bash
terraform apply
```
Terraform te pedirá que escribas `yes` para confirmar. Luego empezará a crear los recursos en AWS.
### Paso 5: Ver los outputs
Al finalizar, Terraform mostrará los valores definidos en `outputs.tf`:
- IP pública de la EC2 (API backend)
- Endpoint de la base de datos
- Nombre del bucket S3 de artefactos
- Nombre del bucket S3 del frontend
- Dominio de CloudFront
---
## 5. Comandos útiles adicionales
| Comando | Para qué sirve |
|---------|----------------|
| `terraform validate` | Revisa que la sintaxis de los archivos esté correcta. |
| `terraform fmt` | Ordena y da formato a los archivos `.tf`. |
| `terraform show` | Muestra el estado actual de la infraestructura. |
| `terraform destroy` | **Elimina** todos los recursos creados. ¡Úsalo con cuidado! |
---
## 6. Checklist antes de ejecutar Terraform
- [ ] Tienes configuradas las credenciales de AWS (`aws configure`).
- [ ] La variable `db_password` no está escrita en el código, viene de un archivo seguro o variable de entorno.
- [ ] Revisaste el `terraform plan` antes de aplicar.
- [ ] Sabes en qué región de AWS se va a crear todo (`us-east-1`, `us-west-2`, etc.).
- [ ] El bucket S3 para el estado remoto ya existe (si usas backend remoto).
- [ ] El `user_data.sh` incluye la llave pública SSH dedicada para el pipeline.
- [ ] El bucket S3 del frontend tiene habilitado el versionamiento de objetos (para rollback del frontend).
- [ ] CloudFront tiene configurado el Origin Access Identity (OAI) u Origin Access Control (OAC) para leer de S3.
- [ ] Route 53 apunta a CloudFront, no a la IP de la EC2.
- [ ] CloudFront tiene un behavior `/api/*` que apunta a la EC2.
- [ ] La EC2 tiene el Security Group configurado para recibir tráfico HTTP desde CloudFront.
---
*Anterior: [`06-scripts-de-despliegue.md`](06-scripts-de-despliegue.md)*
*Siguiente: [`08-seguridad-y-secretos.md`](08-seguridad-y-secretos.md)*
+205
View File
@@ -0,0 +1,205 @@
# 08 - Seguridad y Secretos
> Cómo protegemos las contraseñas, llaves y datos sensibles de `proyectosacc`.
---
## 1. ¿Qué es un "secreto"?
Un **secreto** es cualquier información que no debe ser pública. En `proyectosacc`, los secrets incluyen:
- Contraseñas de bases de datos.
- Llaves SSH privadas.
- Tokens de Telegram.
- Credenciales de AWS (`AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`).
> 💡 **Regla de oro**: si perder esa información causaría un problema de seguridad, es un secreto.
---
## 2. ¿Dónde viven los secrets?
### Opción 1: Bitbucket Repository Variables (la más usada)
En Bitbucket Pipelines podemos guardar variables de entorno que los scripts usan sin exponer su valor.
**Cómo configurarlas:**
1. Ve al repositorio en Bitbucket.
2. Entra a **Repository settings > Pipelines > Repository variables**.
3. Agrega el nombre y el valor.
4. **Marca la casilla "Secured"** 🔒.
**Ventaja**: cuando el pipeline corre, las variables secured aparecen como `***` en los logs. Nadie puede leerlas.
### Opción 2: AWS Secrets Manager
AWS tiene un servicio llamado **Secrets Manager** que guarda secrets de forma segura y permite rotarlos automáticamente.
**Ejemplo de uso en un pipeline de CodeBuild:**
```yaml
env:
secrets-manager:
DB_PASSWORD: "prod/database/password"
```
### Opción 3: AWS Systems Manager Parameter Store
Similar a Secrets Manager, pero más simple y económico. Se usa para guardar configuraciones sensibles.
```yaml
env:
parameter-store:
DATABASE_URL: "/app/database/url"
```
### Opción 4: Archivo `.env` (solo local)
En tu computadora personal puedes tener un archivo `.env` con variables locales. **Este archivo NUNCA debe subirse al repositorio.**
El archivo `.gitignore` del proyecto ya debería incluir `.env` para evitar accidentes.
---
## 3. ¿Qué NUNCA poner en el repositorio?
### ❌ NUNCA hagas esto
```yaml
# Mal ejemplo en bitbucket-pipelines.yml
- step:
script:
- export DB_PASSWORD="supersecreta123"
- export AWS_SECRET_ACCESS_KEY="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
```
```hcl
# Mal ejemplo en Terraform
resource "aws_db_instance" "example" {
password = "mi-contrasena-123"
}
```
```bash
# Mal ejemplo en un script
API_KEY="sk-1234567890abcdef"
```
### ✅ SIEMPRE haz esto
```yaml
# Bien: usa variables de entorno
- step:
script:
- export DB_PASSWORD="$DB_PASSWORD"
```
```hcl
# Bien: usa variables de Terraform
resource "aws_db_instance" "example" {
password = var.db_password
}
```
```bash
# Bien: lee desde una variable de entorno
API_KEY="$API_KEY"
```
---
## 4. ¿Cómo rotar las llaves SSH?
**Rotar** una llave significa crear una nueva y dejar de usar la anterior. Es una buena práctica de seguridad, especialmente si alguien con acceso a la llave privada deja la empresa.
### Paso 1: Generar un nuevo par de llaves
```bash
ssh-keygen -t ed25519 -b 4096 \
-C "bitbucket.pipeline.ci.cd.proyectosacc.thoth.develop@computocontable.com" \
-f bitbucket_pipeline_ci_cd_TO_proyectosacc_server_thoth_develop
```
### Paso 2: Codificar la llave privada en base64
```bash
base64 -i bitbucket_pipeline_ci_cd_TO_proyectosacc_server_thoth_develop | tr -d '\n' > nueva_llave.b64
```
### Paso 3: Actualizar la variable en Bitbucket
1. Copia el contenido de `nueva_llave.b64`.
2. Ve a **Repository settings > Pipelines > Repository variables**.
3. Actualiza la variable `PROYECTOSACC_SSH_KEY` con el nuevo valor.
### Paso 4: Colocar la llave pública en el servidor
```bash
# Copia el contenido del archivo .pub
cat bitbucket_pipeline_ci_cd_TO_proyectosacc_server_thoth_develop.pub
# Conéctate al servidor y agrégala a authorized_keys
ssh ubuntu@<IP_DE_LA_EC2>
sudo su - thoth
nano ~/.ssh/authorized_keys
# Pega la nueva llave pública al final del archivo
> 💡 **Tip**: en un despliegue automatizado con Terraform, esta llave pública se inyecta directamente desde el archivo `user_data`. No hace falta editar `authorized_keys` a mano.
### Paso 5: Probar la conexión
Ejecuta un pipeline de prueba o conéctate manualmente con la nueva llave privada para confirmar que funciona.
### Paso 6: Eliminar la llave anterior
Una vez confirmado que la nueva llave funciona:
1. Borra la llave pública antigua de `~/.ssh/authorized_keys`.
2. Borra la llave privada antigua de tu computadora.
3. Actualiza cualquier otra copia que exista.
---
## 5. Seguridad del frontend en S3 + CloudFront
### Bucket policy para CloudFront (OAI)
El bucket S3 del frontend NO debe ser público. Solo CloudFront puede leer los objetos:
```json
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "AllowCloudFrontOAI",
"Effect": "Allow",
"Principal": {
"CanonicalUser": "<OAI-canonical-user-id>"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::ccsoft-proyectosacc-frontend/*"
}]
}
```
### CORS en S3 (si el frontend llama a la API)
Como el frontend React y la API backend comparten el mismo dominio `https://sacc.ccsoft.mx` (gracias al behavior `/api/*` de CloudFront), **no hay problema de CORS**. Si en el futuro decides mover la API a un subdominio diferente (por ejemplo, `api.sacc.ccsoft.mx`), ahí sí necesitarás configurar CORS en el backend.
### Versionamiento de objetos en S3
Habilita el versionamiento en el bucket del frontend. Así puedes restaurar una versión anterior del sitio si un deploy falla:
```bash
aws s3api put-bucket-versioning \
--bucket ccsoft-proyectosacc-frontend \
--versioning-configuration Status=Enabled
```
---
## 6. Checklist de seguridad básica
- [ ] El archivo `.env` está en `.gitignore`.
- [ ] Ningún archivo del repositorio contiene contraseñas escritas directamente.
- [ ] Las variables de Bitbucket están marcadas como **Secured**.
- [ ] La llave privada SSH dedicada para `proyectosacc` está en formato **base64** en Bitbucket.
- [ ] No se usa acceso SSH por contraseña ni herramientas como `sshpass`.
- [ ] El puerto SSH (22) de la EC2 solo está abierto a IPs conocidas.
- [ ] La base de datos RDS no es accesible desde internet (solo desde la VPC).
- [ ] Los certificados SSL están configurados correctamente en **CloudFront** (HTTPS obligatorio).
- [ ] El bucket S3 del frontend NO es público; solo CloudFront tiene acceso mediante OAI/OAC.
- [ ] El versionamiento de objetos está habilitado en el bucket S3 del frontend.
- [ ] Se ha programado una rotación de llaves SSH al menos una vez al año.
---
*Anterior: [`07-terraform-iac.md`](07-terraform-iac.md)*
*Siguiente: [`09-runbook-deploy.md`](09-runbook-deploy.md)*
+269
View File
@@ -0,0 +1,269 @@
# 09 - Runbook: Deploy Manual
> Qué hacer si el pipeline automático falla y necesitas desplegar a mano.
---
## 1. ¿Cuándo hacer un deploy manual?
Un **deploy manual** significa que tú, persona humana, ejecutas los pasos que normalmente hace el pipeline automático.
Haz un deploy manual cuando:
- 🔴 El pipeline de Bitbucket falló y no se puede reintentar.
- 🟡 Necesitas desplegar una corrección urgente fuera de horario.
- 🟠 El servidor EC2 fue recreado y el pipeline no está configurado todavía.
---
## 2. Paso a paso: deploy manual
Un deploy manual ahora tiene **dos partes**: subir el frontend a S3 + CloudFront, y desplegar la API en la EC2.
---
### PARTE A: Subir el frontend React a S3 e invalidar CloudFront
Esta parte puedes hacerla desde tu computadora local o desde cualquier máquina con AWS CLI configurada.
#### Paso A1: Ve a la carpeta del frontend compilado
```bash
cd /ruta/al/proyecto/frontend/build
```
Si no has compilado el frontend aún:
```bash
npm ci
npm run build
```
#### Paso A2: Sincroniza la carpeta `build/` con S3
```bash
aws s3 sync . s3://ccsoft-proyectosacc-frontend --delete
```
#### Paso A3: Invalida la caché de CloudFront
```bash
aws cloudfront create-invalidation \
--distribution-id <DISTRIBUTION_ID> \
--paths "/*"
```
> 💡 **Nota**: el `DISTRIBUTION_ID` lo encuentras en la consola de AWS o en los outputs de Terraform.
#### Paso A4: Verifica el frontend
Abre tu navegador y visita:
```
https://sacc.ccsoft.mx
```
Si ves la interfaz de SACC, la parte A fue exitosa.
---
### PARTE B: Desplegar la API backend en la EC2
#### Paso B1: Conéctate al servidor EC2
Necesitas la IP pública de la instancia y la **llave SSH dedicada** generada para `proyectosacc`.
```bash
ssh -i ~/.ssh/tu_llave.pem ubuntu@<IP_DE_LA_EC2>
```
O si ya estás dentro de la red de la empresa:
```bash
ssh thoth@<IP_DE_LA_EC2>
```
---
#### Paso B2: Conviértete en el usuario thoth
Si entraste como `ubuntu`, cambia al usuario de despliegue:
```bash
sudo su - thoth
```
---
#### Paso B3: Ve al directorio de despliegue
```bash
cd /home/thoth/deploy
```
---
#### Paso B4: Descarga el artefacto compilado de la API
Si el artefacto está en S3, descárgalo:
```bash
aws s3 cp s3://ccsoft-artifacts-sacc4/develop/proyectosacc-app-1.0.0.jar \
/home/thoth/deploy/artifacts/current/
```
Si no tienes acceso a S3, pide el archivo `.jar` a un compañero y súbelo con `scp`.
---
#### Paso B5: Ejecuta el script de deploy de la API
```bash
bash /home/thoth/deploy/setup/deploy.sh
```
Este script hará lo siguiente automáticamente:
1. Hará backup de la versión anterior.
2. Detendrá el servicio actual.
3. Copiará el nuevo archivo a su lugar.
4. Configurará y recargará `systemd`.
5. Iniciará el nuevo servicio.
6. Hará un health check.
---
#### Paso B6: Verifica que el servicio esté corriendo
```bash
sudo systemctl status proyectosacc-app.service
```
Deberías ver algo como:
```
● proyectosacc-app.service - Proyecto SACC App Service
Loaded: loaded (/etc/systemd/system/proyectosacc-app.service; enabled)
Active: active (running) since Mon 2026-04-14 10:30:00 UTC
```
Si dice `active (running)`, ¡excelente!
---
#### Paso B7: Verifica el health check de la API
```bash
curl http://localhost:8080/actuator/health
```
La respuesta debe incluir:
```json
{"status":"UP"}
```
---
#### Paso B8: Verifica la API desde fuera
Desde tu navegador o con `curl`, prueba un endpoint de la API:
```bash
curl https://sacc.ccsoft.mx/api/actuator/health
```
Si responde correctamente, el deploy manual completo fue exitoso.
---
## 3. Cómo revisar si el deploy funcionó
### Frontend (S3 + CloudFront)
- Abre `https://sacc.ccsoft.mx` en el navegador.
- Revisa la consola de AWS > S3 para ver que los archivos nuevos estén en el bucket.
- Verifica el estado de la invalidación de CloudFront en la consola de AWS.
### API (EC2)
#### Revisar los logs del servicio
```bash
sudo journalctl -u proyectosacc-app.service -n 50 --no-pager
```
#### Revisar el archivo de log de la aplicación
```bash
tail -n 50 /var/log/proyectosacc/proyectosacc-app/proyectosacc-app-service.log
```
#### Revisar que Nginx esté funcionando
```bash
sudo systemctl status nginx
```
#### Revisar que la API responda en el puerto correcto
```bash
ss -tlnp | grep 8080
```
---
## 4. Errores comunes y cómo arreglarlos
### Error 1: "Permission denied" al conectarse por SSH
**Causa**: la llave SSH no tiene los permisos correctos o no está en `authorized_keys`.
**Solución**:
```bash
# En tu computadora local
chmod 600 ~/.ssh/tu_llave.pem
# En el servidor, como thoth
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
```
---
### Error 2: "No such file or directory" al ejecutar deploy.sh
**Causa**: el script no está donde esperas o la ruta es incorrecta.
**Solución**:
```bash
# Busca el script
find /home/thoth -name "deploy.sh"
# Luego ejecútalo con la ruta completa
bash /home/thoth/deploy/setup/deploy.sh
```
---
### Error 3: El servicio no inicia (failed)
**Causa**: puede ser que falta Java, que el puerto 8080 ya está ocupado, o que hay un error en el archivo `.jar`.
**Solución**:
```bash
# Ver qué dice el log
sudo journalctl -u proyectosacc-app.service -n 100 --no-pager
# Ver si el puerto 8080 está ocupado
sudo lsof -i :8080
# Verificar que Java esté instalado
java -version
```
---
### Error 4: Health check falla después del deploy
**Causa**: la aplicación inició pero no responde correctamente, o tarda más de lo esperado.
**Solución**:
```bash
# Espera unos segundos más y vuelve a intentar
curl -v http://localhost:8080/actuator/health
# Revisa si hay errores en el log de la app
tail -n 100 /var/log/proyectosacc/proyectosacc-app/proyectosacc-app-service.log
```
Si sigue fallando, considera ejecutar el **rollback** (ver [`10-runbook-rollback.md`](10-runbook-rollback.md)).
---
*Anterior: [`08-seguridad-y-secretos.md`](08-seguridad-y-secretos.md)*
*Siguiente: [`10-runbook-rollback.md`](10-runbook-rollback.md)*
+235
View File
@@ -0,0 +1,235 @@
# 10 - Runbook: Rollback
> Cómo regresar a la versión anterior de la aplicación cuando algo sale mal.
---
## 1. ¿Qué es un rollback?
Un **rollback** es el proceso de "deshacer" un despliegue. Si la nueva versión de la aplicación tiene errores, el rollback vuelve a poner la versión anterior para que los usuarios no se vean afectados.
> 💡 **Analogía simple**: es como cuando instalas una actualización en tu celular y algo deja de funcionar, así que regresas a la versión anterior del sistema.
---
## 2. ¿Cuándo hacer un rollback?
Haz rollback **inmediatamente** si ves alguna de estas situaciones:
- 🔴 El **health check** falla después del despliegue.
- 🔴 La aplicación se cae al poco tiempo de iniciar.
- 🟡 Los usuarios reportan errores graves que no existían antes.
- 🟡 El pipeline detectó un fallo en el paso de deploy.
- 🟠 El servicio de `systemd` no puede arrancar.
> ⚠️ **Regla de oro**: si dudas, haz rollback. Es mejor tener la versión anterior estable mientras investigas el problema.
---
## 3. Paso a paso: cómo hacer rollback
El rollback ahora tiene **dos partes**: el frontend en S3 y la API en la EC2.
---
### PARTE A: Rollback del frontend en S3
Si el problema es visual (interfaz rota, pantalla en blanco, etc.), restaura el frontend anterior.
#### Paso A1: Lista las versiones anteriores del archivo `index.html`
```bash
aws s3api list-object-versions \
--bucket ccsoft-proyectosacc-frontend \
--prefix index.html \
--query 'Versions[?IsLatest==`false`].[VersionId,LastModified]' \
--output table
```
#### Paso A2: Restaura la versión anterior
Copia el `VersionId` de la versión anterior y restáurala:
```bash
aws s3api copy-object \
--bucket ccsoft-proyectosacc-frontend \
--copy-source ccsoft-proyectosacc-frontend/index.html?versionId=<VERSION_ID> \
--key index.html
```
#### Paso A3: Invalida la caché de CloudFront
```bash
aws cloudfront create-invalidation \
--distribution-id <DISTRIBUTION_ID> \
--paths "/*"
```
#### Paso A4: Verifica el frontend
Abre `https://sacc.ccsoft.mx` y confirma que la interfaz anterior ha vuelto.
---
### PARTE B: Rollback de la API en la EC2
Si el problema es del backend (errores 500, API caída, etc.), restaura la API.
#### Paso B1: Conéctate al servidor EC2
```bash
ssh -i ~/.ssh/tu_llave.pem ubuntu@<IP_DE_LA_EC2>
```
#### Paso B2: Cambia al usuario thoth
```bash
sudo su - thoth
```
#### Paso B3: Ve al directorio de artefactos
```bash
cd /home/thoth/deploy/artifacts
```
#### Paso B4: Revisa los backups disponibles
```bash
ls -lah backup/
```
Verás algo como:
```
proyectosacc-app-20260414_103000.jar
proyectosacc-app-20260413_154500.jar
```
Cada archivo tiene una fecha y hora en su nombre.
#### Paso B5: Identifica cuál es la versión anterior estable
Normalmente es el backup **más reciente antes del deploy fallido**.
```bash
# Ordena por fecha para ver el más reciente
ls -lt backup/ | head -5
```
#### Paso B6: Detén el servicio actual
```bash
sudo systemctl stop proyectosacc-app.service
```
#### Paso B7: Reemplaza el archivo actual con el backup
```bash
# Guarda una copia del archivo fallido (por si necesitas investigarlo después)
mv current/proyectosacc-app.jar current/proyectosacc-app.jar.fallo-$(date +%Y%m%d_%H%M%S)
# Copia el backup al directorio current
cp backup/proyectosacc-app-20260414_103000.jar current/proyectosacc-app.jar
```
> 💡 **Tip**: reemplaza `20260414_103000` con la fecha real del backup que quieres restaurar.
#### Paso B8: Recarga systemd y reinicia el servicio
```bash
sudo systemctl daemon-reload
sudo systemctl start proyectosacc-app.service
```
#### Paso B9: Verifica que el servicio esté corriendo
```bash
sudo systemctl status proyectosacc-app.service
```
Debe decir `active (running)`.
#### Paso B10: Ejecuta el health check
```bash
curl http://localhost:8080/actuator/health
```
Debe responder:
```json
{"status":"UP"}
```
#### Paso B11: Verifica la API desde fuera
```bash
curl https://sacc.ccsoft.mx/api/actuator/health
```
Si todo funciona, el rollback fue exitoso.
---
## 4. Cómo verificar que el rollback funcionó
### Checklist de verificación (API)
- [ ] El servicio `systemd` está en estado `active (running)`.
- [ ] El health check responde `"status":"UP"`.
- [ ] El endpoint `https://sacc.ccsoft.mx/api/actuator/health` responde sin errores.
- [ ] Los usuarios pueden iniciar sesión y usar la aplicación.
- [ ] No hay errores críticos recientes en los logs.
### Checklist de verificación (Frontend)
- [ ] La página `https://sacc.ccsoft.mx` carga sin errores.
- [ ] La invalidación de CloudFront se completó.
- [ ] No hay errores de consola del navegador relacionados con assets faltantes.
### Comandos útiles para verificar
```bash
# Estado del servicio API
sudo systemctl status proyectosacc-app.service
# Health check local
curl -s http://localhost:8080/actuator/health | grep '"status"'
# Health check remoto
curl -s https://sacc.ccsoft.mx/api/actuator/health | grep '"status"'
# Últimos logs
tail -n 30 /var/log/proyectosacc/proyectosacc-app/proyectosacc-app-service.log
# Verificar que Nginx sigue redirigiendo bien la API
sudo systemctl status nginx
# Verificar invalidación de CloudFront
aws cloudfront list-invalidations --distribution-id <DISTRIBUTION_ID>
```
---
## 5. Después del rollback
Una vez que la versión anterior esté estable:
1. **Investiga qué falló** en la nueva versión.
2. **Revisa los logs** del intento fallido.
3. **Notifica al equipo** por Telegram o el canal de comunicación que usen.
4. **Corrige el problema** en el código.
5. **Haz un nuevo deploy** solo cuando estés seguro de que el error está corregido.
### Mensaje de notificación sugerido
```
🚨 Rollback ejecutado en proyectosacc
Motivo: [describe brevemente el problema]
Estado actual: Aplicación estable con versión anterior
Próximo paso: Investigación del error en la nueva versión
```
---
*Anterior: [`09-runbook-deploy.md`](09-runbook-deploy.md)*
*Siguiente: [`11-checklist-primer-deploy.md`](11-checklist-primer-deploy.md)*
+146
View File
@@ -0,0 +1,146 @@
# 11 - Checklist: Primer Deploy
> Lista de verificación de todo lo que debe estar listo antes de hacer el primer despliegue de `proyectosacc`.
---
## 1. Infraestructura AWS
1. [ ] La instancia **EC2 T3.small** con **Ubuntu 22.04** está creada y encendida.
2. [ ] La **EC2** tiene un **Security Group** que permite:
- Puerto `22` (SSH) desde IPs confiables.
- Puerto `80` (HTTP) desde cualquier lugar (solo para la API).
- Puerto `443` (HTTPS) desde cualquier lugar (solo para la API).
3. [ ] La **RDS MariaDB** (`db.t3.micro`) está creada y accesible desde la VPC.
4. [ ] El **bucket S3** para artefactos de la API está creado y la EC2 tiene permisos para leer/escribir en él.
5. [ ] El **bucket S3 para el frontend React** está creado con **Static Website Hosting** habilitado.
6. [ ] El bucket S3 del frontend tiene **versionamiento de objetos** habilitado.
7. [ ] La **distribución CloudFront** está creada, apunta al bucket S3 del frontend, tiene HTTPS y un behavior `/api/*` que apunta a la EC2.
8. [ ] El registro **Route 53** `sacc.ccsoft.mx` apunta a **CloudFront** (no a la IP de la EC2).
9. [ ] El certificado **ACM** para `sacc.ccsoft.mx` está emitido, válido y adjunto a **CloudFront**.
10. [ ] El bucket S3 del frontend tiene un **bucket policy** que permite leer objetos solo a CloudFront (OAI/OAC).
---
## 2. Servidor EC2 (configuración interna)
11. [ ] El usuario `ubuntu` puede conectarse por SSH.
12. [ ] El usuario `thoth` está creado con su directorio `/home/thoth`.
13. [ ] El usuario `osiris` está creado con su directorio `/home/osiris`.
14. [ ] Los directorios de despliegue existen:
```
/home/thoth/deploy/artifacts/backup
/home/thoth/deploy/artifacts/current
/home/thoth/deploy/artifacts/logs
/home/thoth/deploy/artifacts/pids
```
15. [ ] **Nginx** está instalado, configurado como proxy inverso **solo para la API** (`/api` → `localhost:8080`) y corriendo.
16. [ ] **Java** (`openjdk-21-jdk`) está instalado.
17. [ ] **AWS CLI** está instalado y configurado.
18. [ ] Los permisos de carpetas están correctos (`thoth` y `osiris` pueden acceder donde deben).
---
## 3. Llaves SSH
15. [ ] Se generó el **par de llaves SSH dedicado** para `proyectosacc` (no se reutilizan llaves de otros proyectos).
16. [ ] La **llave privada** está codificada en base64 y guardada en **Bitbucket Repository Variables** (`PROYECTOSACC_SSH_KEY`).
17. [ ] La **llave pública** está en `/home/thoth/.ssh/authorized_keys` (inyectada vía Terraform `user_data`).
18. [ ] Se generó el par de llaves SSH para que `thoth` clone repositorios desde Bitbucket.
19. [ ] Las **Access Keys** correspondientes están configuradas en los repositorios de Bitbucket (`ci-cd-commons`, `ci-cd-saac4`).
20. [ ] Se probó la conexión SSH desde el pipeline (o manualmente) y funciona.
---
## 4. Base de datos
21. [ ] La base de datos RDS está accesible desde la EC2.
22. [ ] Se creó el esquema o las tablas necesarias para la aplicación.
23. [ ] La aplicación tiene configurada la URL de conexión a la base de datos.
24. [ ] Las credenciales de la base de datos están guardadas de forma segura (no en el código fuente).
---
## 5. Pipeline de Bitbucket
30. [ ] El archivo `bitbucket-pipelines.yml` está en la raíz del repositorio.
31. [ ] Los 7 pasos del pipeline están configurados correctamente:
- Paso 4 compila tanto el frontend React (`npm run build`) como la API backend.
- Paso 5 sube el frontend a S3 y el `.jar` de la API a S3.
- Paso 7 invalida la caché de CloudFront y reinicia la API.
32. [ ] Las **variables de entorno** están creadas en Bitbucket:
- `PROYECTOSACC_SSH_KEY`
- `PROYECTOSACC_SERVER_IP`
- `PROYECTOSACC_SSH_PORT`
- `PROYECTOSACC_SERVER_USER`
- `PROYECTOSACC_TELEGRAM_BOT_TOKEN`
- `PROYECTOSACC_TELEGRAM_CHAT_ID`
- `AWS_ACCESS_KEY_ID`
- `AWS_SECRET_ACCESS_KEY`
- `CLOUDFRONT_DISTRIBUTION_ID`
- `S3_FRONTEND_BUCKET`
33. [ ] Todas las variables sensibles están marcadas como **Secured** 🔒.
34. [ ] El pipeline puede clonar los repositorios necesarios (`ci-cd-commons`, `ci-cd-saac4`, etc.).
---
## 6. Scripts de despliegue
35. [ ] El script `deploy-frontend-s3.sh` existe y puede subir archivos a S3 + invalidar CloudFront.
36. [ ] El script `setup/deploy.sh` existe en el servidor y tiene permisos de ejecución (solo para la API).
37. [ ] El script `health-check.sh` existe y funciona correctamente.
38. [ ] El script `rollback.sh` existe y tiene al menos un backup de prueba de la API.
39. [ ] El script `notify-telegram.sh` envía mensajes de prueba exitosamente.
---
## 7. Aplicación SACC
40. [ ] El código fuente del **frontend React** compila sin errores (`npm run build`).
41. [ ] El código fuente de la **API backend** compila sin errores localmente.
42. [ ] El pipeline puede generar el artefacto final del frontend (`build/`) y de la API (`.jar`).
43. [ ] El artefacto de la API se puede ejecutar manualmente en la EC2.
44. [ ] La API responde en `http://localhost:8080/actuator/health` cuando corre localmente en la EC2.
---
## 8. Dominio y SSL
45. [ ] El dominio `sacc.ccsoft.mx` resuelve a **CloudFront** (verifica con `dig` o `nslookup`).
46. [ ] **CloudFront** sirve el frontend React por HTTPS sin errores de certificado.
47. [ ] **Nginx** en la EC2 redirige las peticiones de la API correctamente (`/api` → `localhost:8080`).
48. [ ] El endpoint `https://sacc.ccsoft.mx/api/actuator/health` responde correctamente.
49. [ ] Al entrar a `https://sacc.ccsoft.mx` se ve la interfaz de SACC (o al menos una página de prueba del frontend).
---
## 9. Seguridad
50. [ ] El archivo `.env` (si existe) está en `.gitignore`.
51. [ ] No hay contraseñas, tokens ni llaves privadas en el código del repositorio.
52. [ ] No se usa `sshpass` ni acceso SSH por contraseña.
53. [ ] El puerto SSH (22) del Security Group no está abierto a `0.0.0.0/0`.
54. [ ] La base de datos RDS no es pública (solo accesible desde la VPC).
55. [ ] El bucket S3 del frontend NO es público directamente; solo CloudFront accede a él (OAI/OAC).
56. [ ] Los logs sensibles no se imprimen en los archivos de configuración del pipeline.
---
## 10. Comunicación y documentación
57. [ ] El equipo de desarrollo sabe que el primer deploy se va a realizar.
58. [ ] Hay un canal de comunicación activo (Telegram, Slack, etc.) para alertas.
59. [ ] Este checklist ha sido revisado por al menos una persona más.
60. [ ] Se tiene planificado un horario de bajo tráfico para el primer deploy.
---
## ¿Listo?
Si marcaste **todas** las 60 casillas, estás listo para hacer el primer deploy. 🚀
Si te falta alguna, resuélvela antes de continuar. Es mejor tardar un poco más y hacerlo bien, que apurarse y dejar el servicio caído.
---
*Anterior: [`10-runbook-rollback.md`](10-runbook-rollback.md)*