Add complete SACC v4 infrastructure project

- Terraform modules: VPC, EC2, RDS, S3, CloudFront, Route53, Lambda, IAM, Security Groups
- Ansible playbooks for server configuration
- Scripts: create-test-environment.sh, destroy-test-environment.sh, validate-environment.sh
- Documentation: README, QUICKSTART, AGENTS
- Jenkins pipeline for automated deployment
- Jenkins pipeline for environment destruction
This commit is contained in:
Jenkins CI
2026-06-03 04:39:01 +00:00
commit 71be2abd2e
27 changed files with 6424 additions and 0 deletions
+152
View File
@@ -0,0 +1,152 @@
# Pipeline Multi-Entorno - SACC v4
# =================================
Este pipeline de Bitbucket permite desplegar SACC v4 en dos entornos diferentes usando el mismo código base, cambiando solo las variables según la rama.
## Flujo de Trabajo por Ramas
```
┌─────────────────────────────────────────────────────────────┐
│ RAMA 'test' / 'develop' │
│ → Despliegue AUTOMÁTICO a TEST │
│ → Cuenta AWS: 668889063715 │
│ → Variables: environments/test/terraform.tfvars │
│ → Workspace Terraform: test │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ RAMA 'main' / 'master' │
│ → Despliegue MANUAL a PRODUCCIÓN │
│ → Requiere aprobación en Bitbucket │
│ → Cuenta AWS: 523761210517 │
│ → Variables: environments/prod/terraform.tfvars │
│ → Workspace Terraform: prod │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ PULL REQUESTS │
│ → Solo validación (no despliegue) │
│ → Terraform validate + plan │
└─────────────────────────────────────────────────────────────┘
```
## Variables de Repositorio Requeridas
Configurar estas variables en **Bitbucket > Repositorio > Settings > Repository variables**:
### Para TEST (Rama test/develop)
| Variable | Descripción |
|----------|-------------|
| `TEST_AWS_ACCESS_KEY_ID` | Access Key cuenta 668889063715 |
| `TEST_AWS_SECRET_ACCESS_KEY` | Secret Key cuenta 668889063715 |
| `TEST_AWS_SESSION_TOKEN` | Session Token (si aplica) |
### Para PROD (Rama main/master)
| Variable | Descripción |
|----------|-------------|
| `PROD_AWS_ACCESS_KEY_ID` | Access Key cuenta 523761210517 |
| `PROD_AWS_SECRET_ACCESS_KEY` | Secret Key cuenta 523761210517 |
| `PROD_AWS_SESSION_TOKEN` | Session Token (si aplica) |
### Opcionales (Notificaciones)
| Variable | Descripción |
|----------|-------------|
| `TELEGRAM_BOT_TOKEN` | Token del bot de Telegram |
| `TELEGRAM_CHAT_ID` | ID del chat para notificaciones |
## Estructura de Archivos
```
iac-duplicate/
├── terraform/
│ ├── main.tf # Código base (igual para ambos)
│ ├── variables.tf # Variables definidas
│ ├── environments/
│ │ ├── test/
│ │ │ └── terraform.tfvars # Valores TEST
│ │ └── prod/
│ │ └── terraform.tfvars # Valores PROD
│ └── modules/ # Módulos reutilizables
├── ansible/
│ └── playbooks/
│ └── site.yml # Configuración post-deploy
└── bitbucket/
└── bitbucket-pipelines.yml # Este pipeline
```
## Cómo Desplegar
### A TEST (Automático)
```bash
# 1. Hacer cambios en la rama test
git checkout test
git add .
git commit -m "feat: nueva funcionalidad"
git push origin test
# 2. Bitbucket despliega automáticamente
# - Terraform Apply a cuenta 668889063715
# - Ansible configura el servidor
# - Health checks automáticos
```
### A PRODUCCIÓN (Manual)
```bash
# 1. Crear PR de test → main
# 2. Revisar y aprobar PR
# 3. Merge a main
# 4. En Bitbucket, ir a Pipelines
# 5. Ver pipeline de la rama main
# 6. Clic en "Run" para aprobar el despliegue a PROD
# 7. Esperar validación manual
```
## Workspaces Terraform
El pipeline usa workspaces de Terraform para aislar estados:
```bash
# TEST
cd terraform
terraform workspace select test
terraform plan -var-file="environments/test/terraform.tfvars"
# PROD
cd terraform
terraform workspace select prod
terraform plan -var-file="environments/prod/terraform.tfvars"
```
## Custom Pipelines
### Destruir entorno TEST
```bash
# En Bitbucket > Pipelines > Run pipeline
# Seleccionar "destroy-test"
# ⚠️ Esto elimina TODO el entorno de test
```
## Seguridad
- ✅ PROD requiere aprobación manual (trigger: manual)
- ✅ TEST se destruye automáticamente (scheduling)
- ✅ Variables separadas por entorno
- ✅ Workspaces aislados en Terraform
- ✅ Health checks en todos los puertos (8080-8085)
## Troubleshooting
| Problema | Solución |
|----------|----------|
| "Access Denied" en PROD | Verificar credenciales PROD_AWS_* |
| "Workspace not found" | Ejecutar `terraform workspace new test/prod` |
| "Port 808X failed" | Verificar que los JAR estén desplegados en EC2 |
| "Nginx not responding" | Revisar `systemctl status nginx` en EC2 |
## Notas
- El pipeline usa la misma imagen Docker `ccsoft/ccsoft-pipeline:latest`
- Terraform workspaces evitan conflicto de estados
- Los artifacts se pasan entre steps automáticamente
- Las notificaciones Telegram son opcionales
+277
View File
@@ -0,0 +1,277 @@
image: ccsoft/ccsoft-pipeline:latest
# ============================================================
# Pipeline Multi-Entorno: Producción y Pruebas
# ============================================================
# Uso:
# - Rama 'test' o 'develop' → Despliega automáticamente a TEST
# - Rama 'main' o 'master' → Requiere aprobación manual para PROD
# - Pull Requests → Solo validación (sin despliegue)
#
# Variables de Repositorio Requeridas en Bitbucket:
# TEST_AWS_ACCESS_KEY_ID, TEST_AWS_SECRET_ACCESS_KEY, TEST_AWS_SESSION_TOKEN
# PROD_AWS_ACCESS_KEY_ID, PROD_AWS_SECRET_ACCESS_KEY, PROD_AWS_SESSION_TOKEN
# ============================================================
definitions:
caches:
terraform: ~/.terraform.d/plugin-cache
npm: ~/.npm
gradle: ~/.gradle
services:
docker:
memory: 3072
steps:
# Paso reutilizable: Setup SSH y herramientas
- step: &setup-tools
name: Setup Tools
script:
- apt-get update -qq
- apt-get install -y -qq openssh-client jq unzip curl
- terraform --version || (wget -q https://releases.hashicorp.com/terraform/1.5.0/terraform_1.5.0_linux_amd64.zip && unzip -q terraform_1.5.0_linux_amd64.zip && mv terraform /usr/local/bin/)
- ansible --version || apt-get install -y -qq ansible
- aws --version || pip install awscli
- echo "Tools ready"
# Paso reutilizable: Validar Terraform
- step: &validate-terraform
name: Validate Terraform
script:
- cd iac-duplicate/terraform
- terraform init -backend=false
- terraform validate
- terraform fmt -check -recursive
# Paso reutilizable: Plan Terraform (TEST)
- step: &plan-test
name: Plan Terraform (TEST)
deployment: test-plan
script:
- cd iac-duplicate/terraform
- export AWS_ACCESS_KEY_ID="$TEST_AWS_ACCESS_KEY_ID"
- export AWS_SECRET_ACCESS_KEY="$TEST_AWS_SECRET_ACCESS_KEY"
- export AWS_SESSION_TOKEN="$TEST_AWS_SESSION_TOKEN"
- export AWS_DEFAULT_REGION="mx-central-1"
- terraform init
- terraform workspace select test || terraform workspace new test
- terraform plan -var-file="environments/test/terraform.tfvars" -out=tfplan-test
artifacts:
- iac-duplicate/terraform/tfplan-test
# Paso reutilizable: Apply Terraform (TEST)
- step: &apply-test
name: Apply Terraform (TEST)
deployment: test
trigger: automatic
script:
- cd iac-duplicate/terraform
- export AWS_ACCESS_KEY_ID="$TEST_AWS_ACCESS_KEY_ID"
- export AWS_SECRET_ACCESS_KEY="$TEST_AWS_SECRET_ACCESS_KEY"
- export AWS_SESSION_TOKEN="$TEST_AWS_SESSION_TOKEN"
- export AWS_DEFAULT_REGION="mx-central-1"
- terraform init
- terraform workspace select test
- terraform apply -auto-approve tfplan-test
- terraform output -json > terraform-outputs.json
- cat terraform-outputs.json
artifacts:
- iac-duplicate/terraform/terraform-outputs.json
# Paso reutilizable: Ansible Deploy (TEST)
- step: &deploy-test
name: Deploy Application (TEST)
deployment: test-deploy
script:
- cd iac-duplicate/ansible
- EC2_IP=$(cat ../terraform/terraform-outputs.json | jq -r '.ec2_public_ip.value')
- echo "[test]" > inventory
- echo "$EC2_IP ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/sacc4-test-key.pem" >> inventory
- echo "[test:vars]" >> inventory
- echo "ansible_python_interpreter=/usr/bin/python3" >> inventory
- echo "environment=test" >> inventory
- chmod 600 ~/.ssh/sacc4-test-key.pem 2>/dev/null || true
- ansible-playbook -i inventory playbooks/site.yml
# Paso reutilizable: Health Check (TEST)
- step: &health-test
name: Health Check (TEST)
script:
- EC2_IP=$(cat iac-duplicate/terraform/terraform-outputs.json | jq -r '.ec2_public_ip.value')
- echo "Checking health on $EC2_IP..."
- for port in 8080 8081 8082 8083 8084 8085; do
echo "Port $port: $(curl -s -o /dev/null -w '%{http_code}' http://$EC2_IP:$port/actuator/health || echo 'FAILED')";
done
- curl -f -I http://$EC2_IP:80 || echo "Nginx check: WARNING"
# Paso reutilizable: Plan Terraform (PROD)
- step: &plan-prod
name: Plan Terraform (PROD)
deployment: prod-plan
script:
- cd iac-duplicate/terraform
- export AWS_ACCESS_KEY_ID="$PROD_AWS_ACCESS_KEY_ID"
- export AWS_SECRET_ACCESS_KEY="$PROD_AWS_SECRET_ACCESS_KEY"
- export AWS_SESSION_TOKEN="$PROD_AWS_SESSION_TOKEN"
- export AWS_DEFAULT_REGION="mx-central-1"
- terraform init
- terraform workspace select prod || terraform workspace new prod
- terraform plan -var-file="environments/prod/terraform.tfvars" -out=tfplan-prod
artifacts:
- iac-duplicate/terraform/tfplan-prod
# Paso reutilizable: Apply Terraform (PROD) - REQUIERE APROBACIÓN
- step: &apply-prod
name: Apply Terraform (PROD)
deployment: production
trigger: manual
script:
- cd iac-duplicate/terraform
- export AWS_ACCESS_KEY_ID="$PROD_AWS_ACCESS_KEY_ID"
- export AWS_SECRET_ACCESS_KEY="$PROD_AWS_SECRET_ACCESS_KEY"
- export AWS_SESSION_TOKEN="$PROD_AWS_SESSION_TOKEN"
- export AWS_DEFAULT_REGION="mx-central-1"
- terraform init
- terraform workspace select prod
- terraform apply -auto-approve tfplan-prod
- terraform output -json > terraform-outputs-prod.json
artifacts:
- iac-duplicate/terraform/terraform-outputs-prod.json
# Paso reutilizable: Notificación Telegram
- step: &notify
name: Notify Results
script:
- |-
if [ -n "$TELEGRAM_BOT_TOKEN" ] && [ -n "$TELEGRAM_CHAT_ID" ]; then
MESSAGE="✅ SACC4 Pipeline: $BITBUCKET_BRANCH - $BITBUCKET_STEP_KEY completado"
curl -s -X POST "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/sendMessage" \
-d "chat_id=$TELEGRAM_CHAT_ID" \
-d "text=$MESSAGE" >/dev/null
fi
# ============================================================
# PIPELINE POR RAMAS
# ============================================================
pipelines:
# RAMA TEST / DEVELOP → Despliegue automático a TEST
branches:
test:
- step: *setup-tools
- step: *validate-terraform
- step: *plan-test
- step: *apply-test
- step: *deploy-test
- step: *health-test
- step:
<<: *notify
after-script:
- echo "Test environment deployment completed"
develop:
- step: *setup-tools
- step: *validate-terraform
- step: *plan-test
- step: *apply-test
- step: *deploy-test
- step: *health-test
- step:
<<: *notify
after-script:
- echo "Develop environment deployment completed"
# RAMA MAIN / MASTER → Requiere aprobación para PROD
main:
- step: *setup-tools
- step: *validate-terraform
- step: *plan-prod
- step:
<<: *apply-prod
trigger: manual # ⚠️ Requiere clic en "Run" en Bitbucket
- step:
name: Deploy Application (PROD)
deployment: production-deploy
script:
- cd iac-duplicate/ansible
- EC2_IP=$(cat ../terraform/terraform-outputs-prod.json | jq -r '.ec2_public_ip.value')
- echo "[prod]" > inventory
- echo "$EC2_IP ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/sacc4-prod-key.pem" >> inventory
- chmod 600 ~/.ssh/sacc4-prod-key.pem 2>/dev/null || true
- ansible-playbook -i inventory playbooks/site.yml
- step:
name: Health Check (PROD)
script:
- EC2_IP=$(cat iac-duplicate/terraform/terraform-outputs-prod.json | jq -r '.ec2_public_ip.value')
- for port in 8080 8081 8082 8083 8084 8085; do
echo "Port $port: $(curl -s -o /dev/null -w '%{http_code}' http://$EC2_IP:$port/actuator/health || echo 'FAILED')";
done
- step:
<<: *notify
after-script:
- echo "⚠️ PRODUCTION deployment completed - Review required"
master:
- step: *setup-tools
- step: *validate-terraform
- step: *plan-prod
- step:
<<: *apply-prod
trigger: manual
- step:
name: Deploy Application (PROD)
deployment: production-deploy
script:
- cd iac-duplicate/ansible
- EC2_IP=$(cat ../terraform/terraform-outputs-prod.json | jq -r '.ec2_public_ip.value')
- echo "[prod]" > inventory
- echo "$EC2_IP ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/sacc4-prod-key.pem" >> inventory
- chmod 600 ~/.ssh/sacc4-prod-key.pem 2>/dev/null || true
- ansible-playbook -i inventory playbooks/site.yml
- step:
<<: *notify
after-script:
- echo "⚠️ PRODUCTION deployment completed"
# PULL REQUESTS → Solo validación, sin despliegue
pull-requests:
'**':
- step:
name: Code Quality Check
script:
- echo "Checking code quality..."
- terraform fmt -check -recursive || true
- step:
name: Validate Terraform
script:
- cd iac-duplicate/terraform
- terraform init -backend=false
- terraform validate
- step:
name: Test Plan (TEST Environment)
script:
- cd iac-duplicate/terraform
- terraform init -backend=false
- terraform plan -var-file="environments/test/terraform.tfvars"
after-script:
- echo "PR validation completed - No changes applied"
# CUSTOM PIPELINE: Destruir entorno TEST
custom:
destroy-test:
- step:
name: Destroy TEST Environment
deployment: test
trigger: manual
script:
- cd iac-duplicate/terraform
- export AWS_ACCESS_KEY_ID="$TEST_AWS_ACCESS_KEY_ID"
- export AWS_SECRET_ACCESS_KEY="$TEST_AWS_SECRET_ACCESS_KEY"
- export AWS_SESSION_TOKEN="$TEST_AWS_SESSION_TOKEN"
- export AWS_DEFAULT_REGION="mx-central-1"
- terraform init
- terraform workspace select test
- echo "⚠️ WARNING: This will destroy the TEST environment!"
- terraform destroy -var-file="environments/test/terraform.tfvars" -auto-approve
- echo "TEST environment destroyed"