71be2abd2e
- 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
489 lines
17 KiB
Bash
Executable File
489 lines
17 KiB
Bash
Executable File
#!/bin/bash
|
|
# =============================================================================
|
|
# SACC v4 - Script de Creacion de Entorno TEST
|
|
# =============================================================================
|
|
# Cuenta AWS: 668889063715
|
|
# Region: mx-central-1
|
|
#
|
|
# Este script:
|
|
# 1. Valida prerequisitos (AWS CLI, Terraform, credenciales)
|
|
# 2. Verifica que no existan recursos con conflictos de nombres
|
|
# 3. Crea backend S3/DynamoDB para estado Terraform
|
|
# 4. Ejecuta terraform init/plan/apply
|
|
# 5. Genera inventario Ansible
|
|
# 6. Ejecuta playbooks de Ansible
|
|
# 7. Verifica health checks
|
|
#
|
|
# USO:
|
|
# export AWS_ACCESS_KEY_ID=...
|
|
# export AWS_SECRET_ACCESS_KEY=...
|
|
# export AWS_SESSION_TOKEN=...
|
|
# export AWS_DEFAULT_REGION=mx-central-1
|
|
# ./create-test-environment.sh
|
|
#
|
|
# IMPORTANTE: NO ejecutar en produccion
|
|
# =============================================================================
|
|
|
|
set -euo pipefail
|
|
|
|
# Colores para output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# =============================================================================
|
|
# CONFIGURACION
|
|
# =============================================================================
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
|
TERRAFORM_DIR="$PROJECT_ROOT/terraform/environments/test"
|
|
ANSIBLE_DIR="$PROJECT_ROOT/ansible"
|
|
LOG_FILE="$PROJECT_ROOT/logs/create-test-$(date +%Y%m%d-%H%M%S).log"
|
|
ACCOUNT_ID="668889063715"
|
|
REGION="mx-central-1"
|
|
|
|
# Crear directorio de logs
|
|
mkdir -p "$(dirname "$LOG_FILE")"
|
|
|
|
# =============================================================================
|
|
# FUNCIONES DE UTILIDAD
|
|
# =============================================================================
|
|
|
|
log() {
|
|
echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')] INFO:${NC} $1" | tee -a "$LOG_FILE"
|
|
}
|
|
|
|
warn() {
|
|
echo -e "${YELLOW}[$(date '+%Y-%m-%d %H:%M:%S')] WARN:${NC} $1" | tee -a "$LOG_FILE"
|
|
}
|
|
|
|
error() {
|
|
echo -e "${RED}[$(date '+%Y-%m-%d %H:%M:%S')] ERROR:${NC} $1" | tee -a "$LOG_FILE"
|
|
exit 1
|
|
}
|
|
|
|
info() {
|
|
echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')] INFO:${NC} $1" | tee -a "$LOG_FILE"
|
|
}
|
|
|
|
# =============================================================================
|
|
# PASO 1: VALIDAR PREREQUISITOS
|
|
# =============================================================================
|
|
|
|
validate_prerequisites() {
|
|
info "========================================"
|
|
info "PASO 1: Validando prerequisitos"
|
|
info "========================================"
|
|
|
|
# Validar AWS CLI
|
|
if ! command -v aws &> /dev/null; then
|
|
error "AWS CLI no esta instalado. Instalar desde: https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html"
|
|
fi
|
|
log "AWS CLI: $(aws --version | head -1)"
|
|
|
|
# Validar Terraform
|
|
if ! command -v terraform &> /dev/null; then
|
|
error "Terraform no esta instalado. Instalar desde: https://developer.hashicorp.com/terraform/downloads"
|
|
fi
|
|
log "Terraform: $(terraform version | head -1)"
|
|
|
|
# Validar Ansible
|
|
if ! command -v ansible-playbook &> /dev/null; then
|
|
warn "Ansible no esta instalado. Se omitira el paso de Ansible."
|
|
ANSIBLE_AVAILABLE=false
|
|
else
|
|
log "Ansible: $(ansible-playbook --version | head -1)"
|
|
ANSIBLE_AVAILABLE=true
|
|
fi
|
|
|
|
# Validar credenciales AWS
|
|
info "Verificando credenciales AWS..."
|
|
if ! aws sts get-caller-identity &> /dev/null; then
|
|
error "No se pueden validar las credenciales AWS. Asegurate de configurar:\n export AWS_ACCESS_KEY_ID=...\n export AWS_SECRET_ACCESS_KEY=...\n export AWS_SESSION_TOKEN=...\n export AWS_DEFAULT_REGION=mx-central-1"
|
|
fi
|
|
|
|
local caller_identity
|
|
caller_identity=$(aws sts get-caller-identity --output json)
|
|
local account_id
|
|
account_id=$(echo "$caller_identity" | jq -r '.Account')
|
|
local arn
|
|
arn=$(echo "$caller_identity" | jq -r '.Arn')
|
|
|
|
if [ "$account_id" != "$ACCOUNT_ID" ]; then
|
|
error "Cuenta AWS incorrecta. Esperada: $ACCOUNT_ID, Actual: $account_id"
|
|
fi
|
|
|
|
log "Credenciales AWS validas"
|
|
log " Cuenta: $account_id"
|
|
log " ARN: $arn"
|
|
log " Region: $REGION"
|
|
|
|
# Validar region
|
|
local current_region
|
|
current_region=$(aws configure get region 2>/dev/null || echo "$AWS_DEFAULT_REGION")
|
|
if [ "$current_region" != "$REGION" ]; then
|
|
warn "Region actual ($current_region) diferente de la esperada ($REGION)"
|
|
warn "Estableciendo AWS_DEFAULT_REGION=$REGION"
|
|
export AWS_DEFAULT_REGION="$REGION"
|
|
fi
|
|
|
|
# Validar archivo de variables
|
|
if [ ! -f "$TERRAFORM_DIR/terraform.tfvars" ]; then
|
|
error "No existe $TERRAFORM_DIR/terraform.tfvars\nCopiar desde terraform.tfvars.example y completar los valores."
|
|
fi
|
|
log "Archivo terraform.tfvars encontrado"
|
|
|
|
# Validar llaves SSH
|
|
if [ ! -f "$HOME/.ssh/sacc4-test-key.pem" ]; then
|
|
warn "No existe ~/.ssh/sacc4-test-key.pem"
|
|
warn "Generar con: ssh-keygen -t ed25519 -f ~/.ssh/sacc4-test-key -C 'sacc4-test'"
|
|
warn "Subir la llave publica a AWS: aws ec2 import-key-pair ..."
|
|
fi
|
|
}
|
|
|
|
# =============================================================================
|
|
# PASO 2: VERIFICAR CONFLICTOS DE NOMBRES
|
|
# =============================================================================
|
|
|
|
check_conflicts() {
|
|
info "========================================"
|
|
info "PASO 2: Verificando conflictos de nombres"
|
|
info "========================================"
|
|
|
|
local conflicts_found=0
|
|
|
|
# Verificar bucket S3
|
|
local bucket_name
|
|
bucket_name=$(grep "frontend_bucket_name" "$TERRAFORM_DIR/terraform.tfvars" | cut -d'=' -f2 | tr -d ' "')
|
|
log "Verificando bucket S3: $bucket_name"
|
|
if aws s3api head-bucket --bucket "$bucket_name" 2>/dev/null; then
|
|
warn "Bucket S3 '$bucket_name' ya existe"
|
|
conflicts_found=$((conflicts_found + 1))
|
|
else
|
|
log "Bucket S3 disponible"
|
|
fi
|
|
|
|
# Verificar instancia RDS
|
|
local rds_id="sacc4-test-db-prod"
|
|
log "Verificando RDS: $rds_id"
|
|
if aws rds describe-db-instances --db-instance-identifier "$rds_id" 2>/dev/null; then
|
|
warn "RDS '$rds_id' ya existe"
|
|
conflicts_found=$((conflicts_found + 1))
|
|
else
|
|
log "RDS disponible"
|
|
fi
|
|
|
|
# Verificar VPC con mismo CIDR
|
|
local vpc_cidr
|
|
vpc_cidr=$(grep "vpc_cidr" "$TERRAFORM_DIR/terraform.tfvars" | head -1 | cut -d'=' -f2 | tr -d ' "')
|
|
log "Verificando VPC CIDR: $vpc_cidr"
|
|
local existing_vpcs
|
|
existing_vpcs=$(aws ec2 describe-vpcs --filters "Name=cidr,Values=$vpc_cidr" --query 'Vpcs[*].VpcId' --output text)
|
|
if [ -n "$existing_vpcs" ] && [ "$existing_vpcs" != "None" ]; then
|
|
warn "VPC con CIDR $vpc_cidr ya existe: $existing_vpcs"
|
|
conflicts_found=$((conflicts_found + 1))
|
|
else
|
|
log "VPC CIDR disponible"
|
|
fi
|
|
|
|
# Verificar tabla DynamoDB para locks
|
|
local dynamo_table="sacc4-terraform-locks-test-668889063715"
|
|
log "Verificando DynamoDB: $dynamo_table"
|
|
if aws dynamodb describe-table --table-name "$dynamo_table" 2>/dev/null; then
|
|
warn "Tabla DynamoDB '$dynamo_table' ya existe"
|
|
conflicts_found=$((conflicts_found + 1))
|
|
else
|
|
log "Tabla DynamoDB disponible"
|
|
fi
|
|
|
|
# Verificar bucket de estado Terraform
|
|
local state_bucket="sacc4-terraform-state-test-668889063715"
|
|
log "Verificando bucket de estado: $state_bucket"
|
|
if aws s3api head-bucket --bucket "$state_bucket" 2>/dev/null; then
|
|
warn "Bucket de estado '$state_bucket' ya existe"
|
|
conflicts_found=$((conflicts_found + 1))
|
|
else
|
|
log "Bucket de estado disponible"
|
|
fi
|
|
|
|
if [ $conflicts_found -gt 0 ]; then
|
|
warn "Se encontraron $conflicts_found conflictos. Revisar antes de continuar."
|
|
read -p "Continuar de todos modos? (yes/no): " confirm
|
|
if [ "$confirm" != "yes" ]; then
|
|
error "Abortado por el usuario"
|
|
fi
|
|
else
|
|
log "No se encontraron conflictos"
|
|
fi
|
|
}
|
|
|
|
# =============================================================================
|
|
# PASO 3: CREAR BACKEND TERRAFORM (S3 + DynamoDB)
|
|
# =============================================================================
|
|
|
|
create_backend() {
|
|
info "========================================"
|
|
info "PASO 3: Creando backend para estado Terraform"
|
|
info "========================================"
|
|
|
|
local state_bucket="sacc4-terraform-state-test-668889063715"
|
|
local dynamo_table="sacc4-terraform-locks-test-668889063715"
|
|
|
|
# Crear bucket S3
|
|
log "Creando bucket S3: $state_bucket"
|
|
if ! aws s3api head-bucket --bucket "$state_bucket" 2>/dev/null; then
|
|
aws s3api create-bucket \
|
|
--bucket "$state_bucket" \
|
|
--region "$REGION" \
|
|
--create-bucket-configuration LocationConstraint="$REGION"
|
|
log "Bucket creado"
|
|
else
|
|
log "Bucket ya existe"
|
|
fi
|
|
|
|
# Habilitar versionamiento
|
|
log "Habilitando versionamiento en bucket"
|
|
aws s3api put-bucket-versioning \
|
|
--bucket "$state_bucket" \
|
|
--versioning-configuration Status=Enabled
|
|
|
|
# Encriptacion
|
|
log "Configurando encriptacion del bucket"
|
|
aws s3api put-bucket-encryption \
|
|
--bucket "$state_bucket" \
|
|
--server-side-encryption-configuration '{
|
|
"Rules": [{"ApplyServerSideEncryptionByDefault": {"SSEAlgorithm": "AES256"}}]
|
|
}'
|
|
|
|
# Crear tabla DynamoDB
|
|
log "Creando tabla DynamoDB: $dynamo_table"
|
|
if ! aws dynamodb describe-table --table-name "$dynamo_table" 2>/dev/null; then
|
|
aws dynamodb create-table \
|
|
--table-name "$dynamo_table" \
|
|
--attribute-definitions AttributeName=LockID,AttributeType=S \
|
|
--key-schema AttributeName=LockID,KeyType=HASH \
|
|
--billing-mode PAY_PER_REQUEST \
|
|
--region "$REGION"
|
|
log "Tabla DynamoDB creada"
|
|
else
|
|
log "Tabla DynamoDB ya existe"
|
|
fi
|
|
}
|
|
|
|
# =============================================================================
|
|
# PASO 4: TERRAFORM INIT / PLAN / APPLY
|
|
# =============================================================================
|
|
|
|
run_terraform() {
|
|
info "========================================"
|
|
info "PASO 4: Ejecutando Terraform"
|
|
info "========================================"
|
|
|
|
cd "$TERRAFORM_DIR"
|
|
|
|
log "Inicializando Terraform..."
|
|
terraform init
|
|
|
|
log "Ejecutando terraform plan..."
|
|
terraform plan -out=tfplan -var-file=terraform.tfvars
|
|
|
|
info "Revisar el plan anterior. Se crearan los recursos listados arriba."
|
|
read -p "Aplicar cambios? (yes/no): " confirm
|
|
if [ "$confirm" != "yes" ]; then
|
|
error "Abortado por el usuario"
|
|
fi
|
|
|
|
log "Aplicando infraestructura (esto puede tomar 10-15 minutos)..."
|
|
terraform apply tfplan
|
|
|
|
log "Terraform apply completado"
|
|
}
|
|
|
|
# =============================================================================
|
|
# PASO 5: GENERAR INVENTARIO ANSIBLE
|
|
# =============================================================================
|
|
|
|
generate_ansible_inventory() {
|
|
info "========================================"
|
|
info "PASO 5: Generando inventario Ansible"
|
|
info "========================================"
|
|
|
|
cd "$TERRAFORM_DIR"
|
|
|
|
local ec2_ip
|
|
ec2_ip=$(terraform output -raw ec2_public_ip)
|
|
local rds_endpoint
|
|
rds_endpoint=$(terraform output -raw rds_endpoint)
|
|
local s3_bucket
|
|
s3_bucket=$(terraform output -raw frontend_bucket_name)
|
|
|
|
mkdir -p "$ANSIBLE_DIR/inventory"
|
|
|
|
cat > "$ANSIBLE_DIR/inventory/test.ini" << EOF
|
|
[sacc4-test]
|
|
$ec2_ip ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/sacc4-test-key.pem ansible_python_interpreter=/usr/bin/python3
|
|
|
|
[sacc4-test:vars]
|
|
environment=test
|
|
db_endpoint=$rds_endpoint
|
|
s3_bucket=$s3_bucket
|
|
EOF
|
|
|
|
log "Inventario Ansible generado: $ANSIBLE_DIR/inventory/test.ini"
|
|
cat "$ANSIBLE_DIR/inventory/test.ini"
|
|
}
|
|
|
|
# =============================================================================
|
|
# PASO 6: EJECUTAR ANSIBLE
|
|
# =============================================================================
|
|
|
|
run_ansible() {
|
|
info "========================================"
|
|
info "PASO 6: Configurando servidor con Ansible"
|
|
info "========================================"
|
|
|
|
if [ "$ANSIBLE_AVAILABLE" != "true" ]; then
|
|
warn "Ansible no disponible. Omitiendo configuracion."
|
|
info "Para ejecutar manualmente despues:"
|
|
info " cd $ANSIBLE_DIR"
|
|
info " ansible-playbook -i inventory/test.ini playbooks/site.yml"
|
|
return
|
|
fi
|
|
|
|
cd "$ANSIBLE_DIR"
|
|
|
|
log "Ejecutando playbook Ansible..."
|
|
ansible-playbook -i inventory/test.ini playbooks/site.yml
|
|
|
|
log "Ansible completado"
|
|
}
|
|
|
|
# =============================================================================
|
|
# PASO 7: VERIFICAR HEALTH CHECKS
|
|
# =============================================================================
|
|
|
|
verify_health_checks() {
|
|
info "========================================"
|
|
info "PASO 7: Verificando health checks"
|
|
info "========================================"
|
|
|
|
cd "$TERRAFORM_DIR"
|
|
|
|
local ec2_ip
|
|
ec2_ip=$(terraform output -raw ec2_public_ip)
|
|
|
|
log "Verificando conectividad SSH..."
|
|
if ssh -i ~/.ssh/sacc4-test-key.pem -o StrictHostKeyChecking=no -o ConnectTimeout=10 ubuntu@"$ec2_ip" "echo 'OK'" > /dev/null 2>&1; then
|
|
log "SSH: OK"
|
|
else
|
|
warn "SSH: No responde (la instancia puede estar inicializando)"
|
|
fi
|
|
|
|
log "Verificando Nginx..."
|
|
if ssh -i ~/.ssh/sacc4-test-key.pem -o StrictHostKeyChecking=no ubuntu@"$ec2_ip" "sudo systemctl is-active nginx" 2>/dev/null; then
|
|
log "Nginx: Activo"
|
|
else
|
|
warn "Nginx: No activo (esperar a que Ansible termine)"
|
|
fi
|
|
|
|
log "Verificando servicios en puertos 8080-8085..."
|
|
for port in 8080 8081 8082 8083 8084 8085; do
|
|
if ssh -i ~/.ssh/sacc4-test-key.pem -o StrictHostKeyChecking=no ubuntu@"$ec2_ip" "curl -s -o /dev/null -w '%{http_code}' http://localhost:$port/actuator/health 2>/dev/null || echo '000'" 2>/dev/null | grep -q "200"; then
|
|
log "Puerto $port: OK"
|
|
else
|
|
warn "Puerto $port: No responde (esperar despliegue de JARs)"
|
|
fi
|
|
done
|
|
|
|
log "Verificando RDS..."
|
|
local rds_endpoint
|
|
rds_endpoint=$(terraform output -raw rds_endpoint)
|
|
if ssh -i ~/.ssh/sacc4-test-key.pem -o StrictHostKeyChecking=no ubuntu@"$ec2_ip" "mysql -h $rds_endpoint -u sacc_app_user -p -e 'SELECT 1;' 2>/dev/null" > /dev/null 2>&1; then
|
|
log "RDS: Conexion exitosa"
|
|
else
|
|
warn "RDS: No se pudo conectar (verificar credenciales y security groups)"
|
|
fi
|
|
|
|
log "Verificando S3..."
|
|
local s3_bucket
|
|
s3_bucket=$(terraform output -raw frontend_bucket_name)
|
|
if aws s3 ls "s3://$s3_bucket" >/dev/null 2>&1; then
|
|
log "S3: Bucket accesible"
|
|
else
|
|
warn "S3: No se pudo acceder al bucket"
|
|
fi
|
|
}
|
|
|
|
# =============================================================================
|
|
# PASO 8: MOSTRAR RESUMEN
|
|
# =============================================================================
|
|
|
|
show_summary() {
|
|
info "========================================"
|
|
info "RESUMEN DEL DESPLIEGUE"
|
|
info "========================================"
|
|
|
|
cd "$TERRAFORM_DIR"
|
|
|
|
info "Outputs de Terraform:"
|
|
terraform output
|
|
|
|
info ""
|
|
info "Recursos creados en cuenta $ACCOUNT_ID:"
|
|
info " VPC: $(terraform output -raw vpc_id 2>/dev/null || echo 'N/A')"
|
|
info " EC2: $(terraform output -raw ec2_public_ip 2>/dev/null || echo 'N/A')"
|
|
info " RDS: $(terraform output -raw rds_endpoint 2>/dev/null || echo 'N/A')"
|
|
info " S3: $(terraform output -raw frontend_bucket_name 2>/dev/null || echo 'N/A')"
|
|
info " CloudFront: $(terraform output -raw cloudfront_domain_name 2>/dev/null || echo 'N/A')"
|
|
|
|
info ""
|
|
info "Proximos pasos:"
|
|
info " 1. Desplegar JARs de microservicios a /opt/sacc4/*/current/"
|
|
info " 2. Configurar certificado SSL (Let's Encrypt o ACM)"
|
|
info " 3. Verificar DNS: $(terraform output -raw api_subdomain 2>/dev/null || echo 'N/A')"
|
|
info " 4. Ejecutar: $SCRIPT_DIR/validate-environment.sh"
|
|
|
|
info ""
|
|
info "Para destruir el entorno:"
|
|
info " $SCRIPT_DIR/destroy-test-environment.sh"
|
|
}
|
|
|
|
# =============================================================================
|
|
# MAIN
|
|
# =============================================================================
|
|
|
|
main() {
|
|
info "========================================"
|
|
info "SACC v4 - Creacion de Entorno TEST"
|
|
info "Cuenta: $ACCOUNT_ID"
|
|
info "Region: $REGION"
|
|
info "========================================"
|
|
info ""
|
|
info "IMPORTANTE:"
|
|
info " - Este script creara recursos AWS que generan costos"
|
|
info " - Verificar que las credenciales sean de la cuenta correcta"
|
|
info " - No ejecutar en produccion"
|
|
info ""
|
|
read -p "Continuar? (yes/no): " confirm
|
|
if [ "$confirm" != "yes" ]; then
|
|
error "Abortado por el usuario"
|
|
fi
|
|
|
|
validate_prerequisites
|
|
check_conflicts
|
|
create_backend
|
|
run_terraform
|
|
generate_ansible_inventory
|
|
run_ansible
|
|
verify_health_checks
|
|
show_summary
|
|
|
|
log "Proceso completado exitosamente"
|
|
log "Log guardado en: $LOG_FILE"
|
|
}
|
|
|
|
main "$@"
|