Automate Deployments to AWS EC2 with GitHub Actions CI/CD
Set up a complete CI/CD pipeline using GitHub Actions to automatically deploy your application to EC2 whenever you push code to your repository.
What You'll Build
This guide walks you through creating a GitHub Actions workflow that:
- Triggers automatically on every push to your main branch
- Connects securely to your EC2 instance via SSH
- Pulls the latest code from your repository
- Installs dependencies and restarts your application
- Provides deployment status feedback directly in GitHub
Just Need a Quick Redeploy?
If you're managing just a handful of applications or only need to redeploy once or twice, you might not need the full CI/CD setup. Here's the quick manual way:
1. Stop your running app:
pkill -f 'streamlit run' # or pkill -f 'python app.py'2. Pull latest changes (make sure they're committed to GitHub):
cd ~/your-repo && git pull origin main3. Restart your application:
nohup streamlit run app.py > app.log 2>&1 &This manual approach is perfectly fine for small projects. Only invest time in CI/CD automation when you're deploying frequently or managing multiple services.
Prepare Your EC2 Instance
First, ensure your EC2 instance has Git installed and your repository is already cloned. If not, follow these steps:
# Update package manager
sudo yum update -y
# Install Git
sudo yum install git -y
# Clone your repository
git clone git@github.com:YourUsername/your-repo.git
cd your-repoCreate a deployment script that will be executed by GitHub Actions:
#!/bin/bash
set -e
echo "Starting deployment..."
# Navigate to project directory
cd ~/your-repo
# Pull latest changes
echo "Pulling latest code..."
git pull origin main
# Install/update dependencies
echo "Installing dependencies..."
pip install -r requirements.txt
# Restart application (adjust for your app type)
echo "Restarting application..."
pkill -f "streamlit run" || true
nohup streamlit run app.py > app.log 2>&1 &
echo "Deployment complete!"Make the script executable:
chmod +x ~/your-repo/deploy.shGenerate SSH Key for GitHub Actions
On your local machine, generate a dedicated SSH key pair for GitHub Actions to use:
ssh-keygen -t ed25519 -C "github-actions" -f ~/.ssh/github-actions-deployThis creates two files: github-actions-deploy (private key) and github-actions-deploy.pub (public key).
Copy the public key:
cat ~/.ssh/github-actions-deploy.pubAdd it to your EC2 instance's authorized keys:
echo "ssh-ed25519 AAAAC3... github-actions" >> ~/.ssh/authorized_keysAdd Secrets to GitHub Repository
Store your sensitive information securely in GitHub Secrets. Navigate to your repository on GitHub:
- Go to Settings → Secrets and variables → Actions
- Click New repository secret
- Add these three secrets:
EC2_SSH_KEY
Copy the entire contents of your private key file:
cat ~/.ssh/github-actions-deployEC2_HOST
Your EC2 public IP or DNS (e.g., ec2-13-58-123-45.us-east-2.compute.amazonaws.com)
EC2_USERNAME
Your EC2 username (typically ec2-user for Amazon Linux, ubuntu for Ubuntu)
Create GitHub Actions Workflow
In your repository, create the workflow file that will handle automated deployments:
name: Deploy to EC2
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Deploy to EC2
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
cd ~/your-repo
./deploy.shImportant: Replace ~/your-repo with the actual path to your project directory on EC2.
Test Your CI/CD Pipeline
Commit and push your workflow file to trigger the first deployment:
git add .github/workflows/deploy.yml
git commit -m "Add CI/CD workflow"
git push origin mainMonitor the deployment progress:
- Go to your GitHub repository
- Click on the Actions tab
- You should see your workflow running
- Click on it to view detailed logs
Success! If everything is configured correctly, you'll see a green checkmark ✓ indicating successful deployment.
Advanced Enhancements
Add Build Tests Before Deployment
Prevent broken code from reaching production:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Install dependencies
run: pip install -r requirements.txt
- name: Run tests
run: pytest tests/
deploy:
needs: test # Only deploy if tests pass
runs-on: ubuntu-latestDeploy to Multiple Environments
Set up separate staging and production deployments:
on:
push:
branches:
- main # Triggers production deploy
- staging # Triggers staging deploy
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ github.ref == 'refs/heads/main' && secrets.PROD_HOST || secrets.STAGING_HOST }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_SSH_KEY }}
script: cd ~/app && ./deploy.shAdd Slack Notifications
Get notified about deployment status in Slack:
- name: Notify Slack
if: always()
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
webhook_url: ${{ secrets.SLACK_WEBHOOK }}
text: 'Deployment to EC2 ${{ job.status }}'Common Issues & Solutions
❌ Permission denied (publickey)
Ensure the public key is added to ~/.ssh/authorized_keys on EC2 and the private key is correctly added to GitHub Secrets.
❌ deploy.sh: command not found
Make sure the script path in your workflow matches the actual location on EC2 and that it's executable (chmod +x deploy.sh).
❌ Git pull fails
Your EC2 instance needs a deploy key configured for the repository. See the "Deploy Streamlit App" guide for setting this up.
❌ Application doesn't restart
Check the process name in your pkill command matches your actual running process. Use ps aux | grep your-app to verify.
Pro Tips
- Use tmux or systemd to manage your application process for better reliability
- Implement health checks in your deploy script to verify the app started successfully
- Add a rollback mechanism by tagging releases and keeping previous versions
- Consider using AWS CodeDeploy for more advanced deployment strategies like blue-green deployments
- Set up CloudWatch alarms to monitor your EC2 instance health and application metrics
Questions or Issues?
If you run into any problems setting up your CI/CD pipeline, feel free to reach out. I'm happy to help troubleshoot!
Email: its.royniloy@gmail.com