Readme.md changes #58
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: EC2 Deploy | |
on: | |
push: | |
branches: | |
- devops/a4 | |
tags: | |
- deploy-dev | |
- deploy-prod | |
workflow_dispatch: | |
inputs: | |
stage: | |
description: "Select stage to deploy" | |
required: true | |
default: dev | |
type: choice | |
options: | |
- dev | |
- prod | |
env: | |
AWS_REGION: ap-south-1 | |
TF_WORKING_DIR: ./terraform | |
jobs: | |
deploy: | |
runs-on: ubuntu-latest | |
steps: | |
# Checkout Repository | |
- name: Checkout repository | |
uses: actions/checkout@v4 | |
# Configure AWS Credentials | |
- name: Configure AWS credentials | |
uses: aws-actions/configure-aws-credentials@v2 | |
with: | |
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} | |
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} | |
aws-region: ${{ env.AWS_REGION }} | |
# Install Terraform | |
- name: Setup Terraform | |
uses: hashicorp/setup-terraform@v3 | |
# Determine Stage - dev/prod defaults to dev | |
- name: Determine Stage | |
id: set_stage | |
run: | | |
if [[ "${GITHUB_REF}" == "refs/tags/deploy-dev" ]]; then | |
echo "STAGE=dev" >> $GITHUB_ENV | |
elif [[ "${GITHUB_REF}" == "refs/tags/deploy-prod" ]]; then | |
echo "STAGE=prod" >> $GITHUB_ENV | |
elif [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]; then | |
echo "STAGE=${{ github.event.inputs.stage }}" >> $GITHUB_ENV | |
else | |
echo "STAGE=dev" >> $GITHUB_ENV # fallback | |
fi | |
echo "π οΈ Deployment stage: $STAGE" | |
# Clone private repo for prod config | |
- name: Clone Private Repo for Prod Config | |
if: env.STAGE == 'prod' | |
run: | | |
echo "π Cloning private repo for prod configuration..." | |
git clone https://${{ secrets.PRIVATE_REPO_KEY }}@${{ secrets.PRIVATE_REPO }} private-config | |
echo "β Cloned private config repo" | |
# Terraform Init | |
- name: Terraform Init | |
working-directory: ${{ env.TF_WORKING_DIR }} | |
run: terraform init | |
# Terraform Apply (Full Infra) | |
- name: Terraform Apply | |
working-directory: ${{ env.TF_WORKING_DIR }} | |
run: | | |
if [ "${STAGE}" == "prod" ]; then | |
echo "Applying Terraform with private prod configuration..." | |
terraform apply -var-file=../private-config/prod_config.tfvars -auto-approve | |
else | |
echo "Applying Terraform with public dev configuration..." | |
terraform apply -var-file="${STAGE}_config.tfvars" -auto-approve | |
fi | |
# Get Outputs: App IP, Verifier IP, S3 Bucket | |
- name: Get Terraform Outputs | |
working-directory: ${{ env.TF_WORKING_DIR }} | |
run: | | |
INSTANCE_IP=$(terraform output -raw instance_public_ip) | |
S3_BUCKET=$(terraform output -raw s3_log_bucket) | |
echo "INSTANCE_IP=$INSTANCE_IP" >> $GITHUB_ENV | |
echo "S3_BUCKET=$S3_BUCKET" >> $GITHUB_ENV | |
echo "π¦ App IP: $INSTANCE_IP" | |
echo "πͺ£ S3 Bucket: $S3_BUCKET" | |
# Wait for App Initialization | |
- name: Wait for App Initialization | |
run: | | |
echo "β³ Waiting 90 seconds for app EC2 to initialize..." | |
sleep 90 | |
# Validate App Health | |
- name: Validate App Health | |
run: | | |
echo -e "\nπ¦ Full Response from App:\n" | |
curl -s http://${{ env.INSTANCE_IP }}:80 || echo "β Failed to get response" | |
echo -e "\n" | |
echo "Checking app health at http://${{ env.INSTANCE_IP }}:80" | |
for i in {1..10}; do | |
STATUS=$(curl -o /dev/null -s -w "%{http_code}" http://${{ env.INSTANCE_IP }}:80) | |
if [[ "$STATUS" == "200" ]]; then | |
echo "β App is healthy (HTTP 200)" | |
exit 0 | |
else | |
echo "Attempt $i: got HTTP $STATUS" | |
sleep 10 | |
fi | |
done | |
echo "β App failed health check" | |
exit 1 | |
# Provision Verifier EC2 | |
- name: Terraform Apply Verifier EC2 | |
working-directory: ${{ env.TF_WORKING_DIR }} | |
run: | | |
terraform apply -var-file="${STAGE}_config.tfvars" \ | |
-target=aws_instance.log_verifier -auto-approve | |
# Get Verifier IP | |
- name: Get Verifier IP | |
working-directory: ${{ env.TF_WORKING_DIR }} | |
run: | | |
VERIFIER_IP=$(terraform output -raw verifier_instance_public_ip) | |
echo "VERIFIER_IP=$VERIFIER_IP" >> $GITHUB_ENV | |
echo "π Verifier IP: $VERIFIER_IP" | |
# Setup SSH Key for EC2 Access | |
- name: Setup SSH Key for EC2 Access | |
uses: webfactory/[email protected] | |
with: | |
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} | |
# Wait for Verifier EC2 Initialization | |
- name: Wait for Verifier EC2 Initialization | |
run: | | |
echo "β³ Waiting 60 seconds for verifier EC2 to initialize..." | |
sleep 60 | |
# SSH into Verifier EC2 and Validate Logs | |
- name: Validate Logs from Verifier EC2 | |
run: | | |
echo "π Validating logs in S3 from verifier EC2" | |
for attempt in {1..5}; do | |
ssh -o StrictHostKeyChecking=no ubuntu@${VERIFIER_IP} "echo 'β SSH to verifier successful'" && break | |
echo "β³ Verifier not ready, retrying SSH (attempt $attempt)..." | |
sleep 15 | |
done | |
for log in system/cloud-init.log app/my-app.log; do | |
ssh -o StrictHostKeyChecking=no ubuntu@${VERIFIER_IP} \ | |
"if aws s3 ls s3://${S3_BUCKET}/${STAGE}/$log > /dev/null 2>&1; then | |
echo 'β Found: $log'; | |
else | |
echo 'β Missing: $log'; exit 1; | |
fi" | |
done | |
echo "π All required logs are present in S3" | |
# Print Logs from Verifier EC2 | |
- name: Print Logs from Verifier EC2 | |
run: | | |
echo "π Fetching logs from /mylogs/${STAGE} on verifier EC2" | |
for attempt in {1..5}; do | |
ssh -o StrictHostKeyChecking=no ubuntu@${VERIFIER_IP} "echo 'β SSH to verifier successful for log fetch'" && break | |
echo "β³ Verifier not ready for log fetch, retrying SSH (attempt $attempt)..." | |
sleep 15 | |
done | |
ssh -o StrictHostKeyChecking=no ubuntu@${VERIFIER_IP} \ | |
"if [ -f /mylogs/${STAGE}/system/cloud-init.log ]; then | |
echo 'π ====== system/cloud-init.log ======' | |
cat /mylogs/${STAGE}/system/cloud-init.log | tail -n 20 | |
else | |
echo 'β system/cloud-init.log not found' | |
fi" | |
ssh -o StrictHostKeyChecking=no ubuntu@${VERIFIER_IP} \ | |
"if [ -f /mylogs/${STAGE}/app/my-app.log ]; then | |
echo 'π ====== app/my-app.log ======' | |
cat /mylogs/${STAGE}/app/my-app.log | tail -n 20 | |
else | |
echo 'β app/my-app.log not found' | |
fi" | |
echo "β Printed last 20 lines of logs from verifier EC2" | |
# Destroy Infrastructure | |
- name: Destroy Infrastructure | |
if: always() | |
working-directory: ${{ env.TF_WORKING_DIR }} | |
run: | | |
echo "ποΈ Destroying infrastructure for stage: ${STAGE}" | |
if [ "${STAGE}" == "prod" ]; then | |
terraform destroy -var-file=../private-config/prod_config.tfvars -auto-approve | |
else | |
terraform destroy -var-file="${STAGE}_config.tfvars" -auto-approve | |
fi |