Skip to content

Redeploy site

Redeploy site #216

Workflow file for this run

name: Terraform CI/CD
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
permissions:
contents: read
id-token: write
env:
ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }}
ARM_CLIENT_SECRET: ${{ secrets.ARM_CLIENT_SECRET }}
ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }}
ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }}
jobs:
terraform:
name: Terraform
runs-on: ubuntu-latest
environment: qa
steps:
- name: 📦 Checkout code
uses: actions/checkout@v3
- name: ⚙️ Setup Terraform
uses: hashicorp/setup-terraform@v2
with:
terraform_version: 1.5.0
- name: 🔐 Azure Login with Service Principal
uses: azure/login@v1
with:
creds: >-
{
"clientId": "${{ secrets.ARM_CLIENT_ID }}",
"clientSecret": "${{ secrets.ARM_CLIENT_SECRET }}",
"subscriptionId": "${{ secrets.ARM_SUBSCRIPTION_ID }}",
"tenantId": "${{ secrets.ARM_TENANT_ID }}"
}
- name: 🧪 Verify Azure login
run: az account show
- name: 🏗️ Ensure Terraform remote backend exists
run: |
az group create --name soft-tfstate-rg --location eastus
az storage account create \
--name softsastate \
--resource-group soft-tfstate-rg \
--location eastus \
--sku Standard_LRS \
--encryption-services blob
az storage container create \
--name tfstate \
--account-name softsastate
- name: 📥 Terraform Init
run: |
terraform -chdir=infra init \
-backend-config="resource_group_name=soft-tfstate-rg" \
-backend-config="storage_account_name=softsastate" \
-backend-config="container_name=tfstate" \
-backend-config="key=terraform.tfstate"
- name: 🧹 Optional Unlock (if lock is active)
run: |
terraform -chdir=infra init
LOCK_FILE=".terraform/terraform.tfstate.lock.info"
if [ -f "infra/$LOCK_FILE" ]; then
LOCK_ID=$(jq -r '.ID' "infra/$LOCK_FILE")
echo "🔓 Lock found: $LOCK_ID. Attempting to unlock..."
terraform -chdir=infra force-unlock -force "$LOCK_ID"
else
echo "✅ No lock file found. Continuing..."
fi
- name: 🧹 Terraform Format
run: |
terraform -chdir=infra fmt -check -diff -recursive -no-color || true
- name: 📝 Generate terraform.tfvars
run: |
cat > infra/terraform.tfvars <<EOF
subscription_id = "${{ secrets.ARM_SUBSCRIPTION_ID }}"
client_id = "${{ secrets.ARM_CLIENT_ID }}"
client_secret = "${{ secrets.ARM_CLIENT_SECRET }}"
tenant_id = "${{ secrets.ARM_TENANT_ID }}"
allowed_ssh_ip = "${{ secrets.MY_IP_ADDRESS }}"
mysql_user = "${{ secrets.MYSQL_USER }}"
mysql_admin_password = "${{ secrets.MYSQL_ADMIN_PASSWORD }}"
ssh_public_key = "${{ secrets.VM_SSH_PUB_KEY }}"
EOF
- name: 🔍 Terraform Validate
run: terraform -chdir=infra validate
- name: 📋 Terraform Plan
run: terraform -chdir=infra plan -input=false -var-file=terraform.tfvars
- name: 🚀 Terraform Apply
if: github.ref == 'refs/heads/master'
run: terraform -chdir=infra apply -auto-approve -input=false -var-file=terraform.tfvars
# - name: 📄 Generate Terraform outputs
# run: |
# terraform -chdir=infra output -json > infra/tf_outputs.json
# echo "✅ tf_outputs.json generated"
- name: 📄 Generate Terraform outputs
run: |
"$TERRAFORM_CLI_PATH/terraform-bin" -chdir=infra output -json > infra/tf_outputs.json
# - name: 🐛 Debug Terraform outputs
# run: |
# cat infra/tf_outputs.json
- name: 📦 Upload inventory.ini as artifact
uses: actions/upload-artifact@v4
with:
name: inventory
path: ansible/inventory.ini
- name: 📤 Export Terraform outputs to GitHub ENV
run: |
echo "📥 Exporting variables to GitHub ENV..."
echo "APP_SERVICE_NAME=$(jq -r '.app_service_name.value' infra/tf_outputs.json)" >> $GITHUB_ENV
echo "RESOURCE_GROUP_NAME=$(jq -r '.resource_group_name.value' infra/tf_outputs.json)" >> $GITHUB_ENV
echo "LB_API_URL=$(jq -r '.lb_api_url.value' infra/tf_outputs.json)" >> $GITHUB_ENV
echo "LB_API_PORT=$(jq -r '.api_public_port.value' infra/tf_outputs.json)" >> $GITHUB_ENV
- name: 🔧 Compose LB API URL
run: |
echo "LB_API_URL=${LB_API_URL}:${LB_API_PORT}" >> $GITHUB_ENV
- name: 🗃️ Run Script Configure Jumpbox
run: |
chmod +x ./ansible/configure-jumpbox.sh
# Get outputs from Terraform
JUMP_HOST=$(terraform -chdir=infra output -raw control_node_public_ip | grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' | tail -n1)
JUMP_USER=$(terraform -chdir=infra output -raw ssh_user | grep -Eo '^[a-zA-Z0-9]+' | tail -n1)
SSH_KEY_CONTENT="${{ secrets.VM_SSH_KEY }}"
ANSIBLE_DIR=./ansible
REMOTE_DIR=/home/${JUMP_USER}/ansible-setup
./ansible/configure-jumpbox.sh "$JUMP_HOST" "$JUMP_USER" "$SSH_KEY_CONTENT" "$ANSIBLE_DIR" "$REMOTE_DIR"
- name: 🛢️ Run Script Deploy Database
run: |
chmod +x ./ansible/deploy-db-from-local.sh
# ✅ Ejecuta y guarda el resultado de terraform output
# Get clean DB_HOST - Ultimate reliable method
DB_HOST=$(terraform -chdir=infra output -raw mysql_fqdn 2>&1 | grep -oE '[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' | head -n1)
# echo "Extracted DB_HOST='$DB_HOST'"
# Fallback if raw output fails
if [ -z "$DB_HOST" ]; then
DB_HOST=$(terraform -chdir=infra output mysql_fqdn | grep -oE '[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' | head -n1)
# echo "Fallback extracted DB_HOST='$DB_HOST'"
fi
# Final validation
if [[ ! "$DB_HOST" =~ ^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
echo "ERROR: Could not extract valid DB_HOST"
echo "Raw terraform output:"
terraform -chdir=infra output mysql_fqdn
exit 1
fi
DB_USER="${{ secrets.MYSQL_USER }}"
DB_PASS="${{ secrets.MYSQL_ADMIN_PASSWORD }}"
DB_NAME="movie_analyst"
JUMP_HOST=$(terraform -chdir=infra output -raw control_node_public_ip | grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' | tail -n1)
JUMP_USER=$(terraform -chdir=infra output -raw ssh_user | grep -Eo '^[a-zA-Z0-9]+' | tail -n1)
./ansible/deploy-db-from-local.sh "$DB_HOST" "$DB_USER" "$DB_PASS" "$DB_NAME" "$JUMP_HOST" "$JUMP_USER"
- name: 🧩 Run Script Deploy API from Jumpbox to VMs
run: |
chmod +x ./ansible/deploy-api-jumpbox-to-vms.sh
# Get clean DB_HOST - Ultimate reliable method
DB_HOST=$(terraform -chdir=infra output -raw mysql_fqdn 2>&1 | grep -oE '[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' | head -n1)
# echo "Extracted DB_HOST='$DB_HOST'"
# Fallback if raw output fails
if [ -z "$DB_HOST" ]; then
DB_HOST=$(terraform -chdir=infra output mysql_fqdn | grep -oE '[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' | head -n1)
# echo "Fallback extracted DB_HOST='$DB_HOST'"
fi
# Final validation
if [[ ! "$DB_HOST" =~ ^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
echo "ERROR: Could not extract valid DB_HOST"
echo "Raw terraform output:"
terraform -chdir=infra output mysql_fqdn
exit 1
fi
JUMP_HOST=$(terraform -chdir=infra output -raw control_node_public_ip | grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' | tail -n1)
JUMP_USER=$(terraform -chdir=infra output -raw ssh_user | grep -Eo '^[a-zA-Z0-9]+' | tail -n1)
DB_USER="${{ secrets.MYSQL_USER }}"
DB_PASS="${{ secrets.MYSQL_ADMIN_PASSWORD }}"
DB_NAME="movie_analyst"
# echo "=== Final Variables ==="
# echo "DB_HOST: $DB_HOST"
# echo "JUMP_HOST: $JUMP_HOST"
# echo "JUMP_USER: $JUMP_USER"
./ansible/deploy-api-jumpbox-to-vms.sh "$DB_HOST" "$DB_USER" "$DB_PASS" "$DB_NAME" "$JUMP_HOST" "$JUMP_USER"
- name: Deploy Frontend
run: |
chmod +x ./ansible/deploy-frontend.yml
echo "Using values:"
echo "APP_SERVICE_NAME=$APP_SERVICE_NAME"
echo "RESOURCE_GROUP_NAME=$RESOURCE_GROUP_NAME"
echo "LB_API_URL=$LB_API_URL"
ansible-playbook ansible/deploy-frontend.yml -i localhost,
env:
APP_SERVICE_NAME: ${{ env.APP_SERVICE_NAME }}
RESOURCE_GROUP_NAME: ${{ env.RESOURCE_GROUP_NAME }}
LB_API_URL: ${{ env.LB_API_URL }}
- name: 🌐 Show frontend URL
run: |
echo "✅ Your frontend is deployed and available at:"
echo "https://${APP_SERVICE_NAME}.azurewebsites.net"
env:
APP_SERVICE_NAME: ${{ env.APP_SERVICE_NAME }}