-
- Click: New Repository
- Repository name: 'repo name'
- Visibility: Public
- Initialize with:
- ✅ Add a README file
- ❌ No .gitignore or license needed right now (we can add later)
- Click Create repository
- Open your terminal (VS Code terminal, Git Bash, or macOS Terminal — anything works).
- Run this commands:
git clone https://github.com/<your-username>/automated-cicd-nodejs-aws-ec2-github-actions.gitcd automated-cicd-nodejs-aws-ec2-github-actionsReplace <your-username> with your actual GitHub username.
This will:
- Download your new repo to your machine
- Move you inside the project folder
- Prepare you to start building the Node.js app
- In your project folder, run:
npm init -y- This creates
package.json.
npm install jest --save-devmkdir src tests- Create:
src/index.js
function add(a, b) {
return a + b;
}
module.exports = add;- Create:
tests/app.test.js
const add = require('../src/index');
test('adds numbers correctly', () => {
expect(add(2, 3)).toBe(5);
});- Open
package.jsonand replace the"scripts"section with:
"scripts": {
"test": "jest",
"build": "echo 'Build step placeholder'"
}- This gives us:
- A test command
- A build command (placeholder for now)
git add .
git commit -m "Add Node.js app and tests"
git pushThis workflow will automatically:
- Install dependencies
- Run tests
- Build the app
- Upload the build artifact This is your Continuous Integration pipeline.
In your project root, create:
.github/workflows
Inside .github/workflows, create:
ci.yaml
Paste this workflow:
name: CI Pipeline
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build-test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 18
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
- name: Build project
run: npm run build
- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: build-output
path: .This workflow teaches you:
- Triggers
- Runners
- Steps
- Using marketplace actions
- Caching
- Artifacts
git add .
git commit -m "Add CI workflow"
git pushGo to your GitHub repo → Actions tab You should see: CI Pipeline — running This means your automation is alive.
Go to AWS Console → EC2 → Instances → Launch Instance Use these settings:
- Name:
cicd-nodejs-ec2 - AMI: Amazon Linux 2 (recommended)
- Instance type: t2.micro (free tier)
- Key pair: Create or choose an existing one
- Security group:
- Allow SSH (22) from your IP
- Allow HTTP (80) from anywhere (for app access) Click Launch Instance.
In your terminal:
chmod 400 your-key.pem
ssh -i your-key.pem ec2-user@<EC2-Public-IP>Replace:
your-key.pem→ your private key file<EC2-Public-IP>→ from AWS console If you’re on Windows and using Git Bash, same command works.
Run
sudo yum update -y
sudo yum install -y nodejs gitVerify
node -v
npm -vPM2 keeps your Node.js app running even after deployment.
sudo npm install -g pm2sudo mkdir -p /var/www/myapp
sudo chown ec2-user:ec2-user /var/www/myappThis is where GitHub Actions will upload your build files.
Your GitHub Actions workflow will need:
- The EC2 public IP
- The EC2 username
- Your private SSH key These must be stored securely in GitHub Secrets.
In your GitHub repo: Settings → Secrets and variables → Actions → New repository secret You will create three secrets.
- Name:
EC2_HOST - Value: your EC2 public IPv4 address Example:
54.175.34.160Click Add secret.
This depends on your AMI:
- For Amazon Linux 2 →
ec2-user - For Ubuntu →
ubuntuYou used Amazon Linux 2 earlier, so: - Name:
EC2_USER - Value:
ec2-userClick Add secret.
This is your private key (.pem) content.
- Open your
.pemfile in a text editor - Copy the entire content including:
-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----
- Create a new secret:
- Name:
EC2_SSH_KEY - Value: paste the entire key Click Add secret.
This workflow will:
- Download the build artifact from the CI pipeline
- SSH into your EC2 instance
- Copy the build files
- Restart your Node.js app using PM2
Inside your project, go to:
.github/workflows/
Create a new file:
cd-ec2.yaml
Paste this workflow:
name: Deploy to EC2
on:
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Download build artifact
uses: actions/download-artifact@v4
with:
name: build-output
path: build/
- name: Add SSH key
run: |
echo "${{ secrets.EC2_SSH_KEY }}" > key.pem
chmod 600 key.pem
- name: Copy files to EC2
run: |
scp -o StrictHostKeyChecking=no -i key.pem -r build/* \
${{ secrets.EC2_USER }}@${{ secrets.EC2_HOST }}:/var/www/myapp/
- name: Restart app on EC2
run: |
ssh -o StrictHostKeyChecking=no -i key.pem \
${{ secrets.EC2_USER }}@${{ secrets.EC2_HOST }} \
"pm2 restart all || pm2 start /var/www/myapp/index.js"
git add .
git commit -m "Add CD workflow for EC2 deployment"
git push
Go to your GitHub repo → Actions tab You should now see:
- CI Pipeline
- Deploy to EC2 The CD pipeline will show a Run workflow button.
This is where you trigger the CD workflow manually and watch your app deploy to your EC2 instance.
In your GitHub repo:
- Click Actions
- On the left side, select Deploy to EC2
- Click the Run workflow button (top right) A small dropdown appears → click Run workflow again. This will start your deployment job.
You should see steps like:
- Checkout code
- Download build artifact
- Add SSH key
- Copy files to EC2
- Restart app on EC2 If everything is correct, the workflow will turn green.
SSH into your EC2 instance:
ssh -i your-key.pem ec2-user@<EC2-Public-IP>
Then check PM2:
pm2 status
You should see your app running.
- Built a fully automated CI/CD pipeline using GitHub Actions and AWS EC2
- CI workflow runs tests, builds the app, and uploads optimized artifacts
- CD workflow deploys to EC2 automatically with zero manual steps
- Deployment is verified live via PM2, demonstrating production‑ready DevOps automation