Deployment Flow Guide

Complete AWS setup and GitHub Actions deployment workflow CI/CD

1
🏗️

AWS Infrastructure Setup

📋 Overview

Set up secure AWS infrastructure with VPC, subnets, and EC2 instances for deployment.

🌐 Step 1.1: Create VPC

  1. Navigate to AWS VPC Console
  2. Click "Create VPC"
  3. Choose "VPC only" option
  4. Name: management_app (example name)
  5. IPv4 CIDR block: 10.0.0.0/16
  6. Tenancy: Default
  7. Click "Create VPC"

🏠 Step 1.2: Create Subnets

Public Subnet (Application Server)

  1. Navigate to "Subnets" → Click "Create subnet"
  2. Name: public (example name)
  3. VPC: Select your VPC (management_app)
  4. IPv4 CIDR: 10.0.1.0/24
  5. Click "Create subnet"

Private Subnet (Database Server)

  1. Click "Create subnet" again
  2. Name: private (example name)
  3. VPC: Select your VPC (management_app)
  4. IPv4 CIDR: 10.0.2.0/24
  5. Click "Create subnet"

🌍 Step 1.3: Create Internet Gateway

  1. Navigate to "Internet Gateways"
  2. Click "Create internet gateway"
  3. Name: management_app (example name)
  4. Click "Create internet gateway"
  5. Select gateway → Actions → "Attach to VPC"
  6. Select your VPC → "Attach internet gateway"

🛤️ Step 1.4: Configure Route Tables

Create Public Route Table

  1. Navigate to "Route Tables" → "Create route table"
  2. Name: management_app_public (example name)
  3. VPC: Select your VPC
  4. Click "Create route table"

Configure Public Routes

  1. Select route table → Routes tab → "Edit routes"
  2. Add route: Destination 0.0.0.0/0
  3. Target: Internet Gateway → Select your gateway
  4. Save changes

Associate with Public Subnet

  1. Subnet associations tab → "Edit subnet associations"
  2. Select the public subnet
  3. Save associations

🔀 Step 1.5: Create NAT Gateway

  1. Navigate to "NAT Gateways" → "Create NAT gateway"
  2. Name: asef (example name)
  3. Subnet: Select private subnet
  4. Connectivity type: Public
  5. Click "Allocate Elastic IP"
  6. Click "Create NAT gateway"

Configure Private Route Table

  1. Find route table for private subnet
  2. Edit routes → Add route
  3. Destination: 0.0.0.0/0
  4. Target: NAT Gateway → Select your gateway
  5. Save changes

🖥️ Step 1.6: Create EC2 Instances

Database Instance (t2.micro - Private)

  1. EC2 Console → "Launch Instance"
  2. Name: database-server (example name)
  3. Instance type: t2.micro
  4. Create/select key pair
  5. VPC: Your custom VPC
  6. Subnet: private subnet
  7. Auto-assign public IP: Disable
  8. Security Group: Allow SSH (22) and MySQL (3306) from VPC CIDR
  9. Storage: Up to 50 GB if needed
  10. Launch instance

Application Instance (t2.small - Public)

  1. "Launch Instance" again
  2. Name: app-server (example name)
  3. Instance type: t2.small
  4. Same key pair as database
  5. VPC: Your custom VPC
  6. Subnet: public subnet
  7. Auto-assign public IP: Enable
  8. Security Group: Allow SSH (22), HTTP (80), HTTPS (443) from 0.0.0.0/0
  9. Launch instance

📝 Step 1.7: Collect Instance Information

Important: After both instances are running, collect this information for GitHub secrets.
Application Instance
• Public IP Address
• Private IP Address
Database Instance
• Private IP Address
SSH Key
• .pem file contents
2
🔐

GitHub Secrets Configuration

🔐 Current Secrets

Your repository already has these secrets configured:

EC2_HOST
Public IP of application server
EC2_SSH_KEY
SSH private key (.pem file contents)
EC2_USER
EC2 instance username (ubuntu)
APP_DIR
Application directory path
DB_EC2_HOST
Private IP of database server
DB_EC2_SSH_KEY
Database server SSH key
DB_EC2_USER
Database server username
DB_NAME
Database name
DB_PASSWORD
Database password
DB_USER_NAME
Database username
SERVICE_NAME
Systemctl service name
DOMAIN_NAME
Domain name
✅ Great! Your secrets are already configured. Just ensure they have the correct values from your AWS setup.

🔄 Update Secrets with AWS Values

Navigate to: Repository → Settings → Secrets and variables → Actions

Update these secrets with your AWS instance information:
• EC2_HOST = [Public IP of app server]
• DB_EC2_HOST = [Private IP of database server]
• EC2_SSH_KEY = [Contents of your .pem file]
3
⚙️

Deployment Pipeline Configuration

🎯 Deployment Triggers

🔄 Automatic Push Trigger

Automatically deploys when code is pushed to the main branch.

on: push: branches: [main]

👆 Manual Trigger

Deploy manually from GitHub Actions interface.

on: workflow_dispatch: {}

📋 Deployment Process Steps

1. Pre-Deployment Status Check

  • Check if application is already deployed
  • Determine first deployment vs. update
  • Set deployment flags for database setup

2. Database Setup (First Deployment Only)

  • Setup SSH connectivity to database server
  • Test database connection
  • Run database migrations
  • Generate database schema
  • Seed database with initial data

3. System Setup (First Deployment)

# Install required packages sudo apt update && sudo apt upgrade -y # Install Node.js 18 LTS curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - sudo apt-get install -y nodejs # Install Nginx, Git, MySQL client sudo apt install nginx git mysql-client -y

4. Application Deployment

  • Clone/update repository from main branch
  • Install dependencies with npm ci
  • Run database operations
  • Build Next.js application
  • Configure systemctl service
  • Setup Nginx reverse proxy
  • Start/restart services

5. SSL Certificate Installation (First Deployment)

🔐 Automatic SSL: The deployment automatically installs SSL certificates using Certbot if DOMAIN_NAME is configured.
  • Install Certbot and python3-certbot-nginx
  • Issue SSL certificate for configured domain
  • Configure auto-renewal
  • Test certificate renewal process
# Automatic certificate installation sudo certbot --nginx \ --non-interactive \ --agree-tos \ --email your-email@example.com \ --domains your-domain.com \ --redirect
4
🚀

Manual Deployment Trigger

🚀 How to Manually Deploy

  1. Navigate to your GitHub repository
  2. Click on the "Actions" tab
  3. Select "Main Deployment Pipeline"
  4. Click "Run workflow" button
  5. Select branch: main
  6. Click "Run workflow" to start deployment
✅ Deployment Status: Monitor the deployment progress in real-time through the GitHub Actions interface.

📊 Deployment Verification

Service Status Check

sudo systemctl status [SERVICE_NAME] sudo systemctl status nginx

Application Health Check

curl http://localhost:3000 curl http://[PUBLIC_IP]

Database Connection Test

mysql -h [DB_HOST] -u [DB_USER] -p[DB_PASSWORD] -e "SHOW TABLES;"
5
🔧

Troubleshooting & Monitoring

🔧 Common Issues & Solutions

SSH Connection Failed

  • Verify EC2_SSH_KEY secret format is correct
  • Check security group allows SSH access
  • Ensure public IP is current in EC2_HOST

Database Connection Failed

  • Verify database instance is running
  • Check security group allows port 3306 from VPC
  • Confirm database credentials in secrets

Application Not Accessible

  • Check if Nginx is running
  • Verify security group allows HTTP/HTTPS traffic
  • Confirm application runs on correct port

🔐 SSL Certificate Issues

Problem: Site not available on HTTPS or certificate not issued automatically

Manual SSL Certificate Installation:

  1. SSH into your server using your private key
  2. Run Certbot manually with domain selection
  3. Select the domain number when prompted
  4. Certificate will be issued if domain is properly configured
# SSH into server ssh -i your-key.pem ubuntu@your-server-ip
# Run Certbot manually sudo certbot --nginx # When prompted, select the number for your domain # Example: # 1: your-domain.com # 2: www.your-domain.com # Select: 1 (or appropriate number)

Prerequisites for SSL to work:

  • Domain must point to your server's public IP
  • DNS A record: your-domain.com → your-server-ip
  • Nginx must be running and properly configured
  • Port 80 and 443 must be open in security groups
✅ Verification: After certificate installation, your site should be accessible via https://your-domain.com