Day 6: Building a Cloud-Native CI/CD Pipeline with GitHub Actions

Overview:
Continuous Integration (CI) and Continuous Deployment (CD) are essential for modern cloud-native applications. Automating the building, testing, and deployment of your application speeds up development and ensures consistent code quality. In this tutorial, we’ll walk through setting up a CI/CD pipeline using GitHub Actions, a powerful and flexible tool that allows you to automate workflows directly from your GitHub repository.

By the end of this guide, you will have a cloud-native CI/CD pipeline that automatically tests, builds, and deploys your application to a cloud platform (AWS or Heroku) whenever you push changes to your GitHub repository.


Prerequisites:

  • GitHub account.
  • A cloud platform to deploy (AWS, Heroku, or any other).
  • A sample application (Node.js or Python, for example) that you want to deploy.

Step 1: Prepare the Application

Before we set up the CI/CD pipeline, let’s create a sample Node.js application that we’ll use throughout this tutorial. Feel free to adapt this example for other languages or frameworks like Python, Ruby, etc.

  1. Create a new project directory:
mkdir github-actions-demo
cd github-actions-demo
  1. Initialize a new Node.js project:
npm init -y
  1. Install Express.js:
npm install express
  1. Create an app.js file:
touch app.js

Add the following content to app.js:

const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;

app.get('/', (req, res) => {
  res.send('Hello from CI/CD Pipeline!');
});

app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});
  1. Create a package.json script to start the app:

In the scripts section of package.json, add:

"start": "node app.js"

Now, you have a simple Node.js application that you can deploy.

See also  Day 1: Deploying a Serverless API on AWS Lambda

Step 2: Push the Code to GitHub

  1. Create a GitHub repository by going to GitHub and clicking New repository. Name the repository something like github-actions-demo.
  2. In your local project directory, initialize Git and push the code to GitHub:
git init
git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin https://github.com/your-username/github-actions-demo.git
git push -u origin main

Now, your code is in GitHub, and we’re ready to set up CI/CD using GitHub Actions.


Step 3: Set Up GitHub Actions

GitHub Actions uses workflows defined in YAML files to automate your tasks. These workflows are stored in the .github/workflows directory in your repository.

  1. Create the directory for GitHub Actions workflows:
mkdir -p .github/workflows
  1. Create a workflow file:
touch .github/workflows/ci-cd.yml
  1. Define the workflow for CI/CD:

Here’s an example of a CI/CD pipeline that runs tests, builds the app, and deploys it to Heroku.

name: CI/CD Pipeline

on:
  push:
    branches:
      - main  # Trigger workflow when code is pushed to the main branch

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Set up Node.js
        uses: actions/setup-node@v2
        with:
          node-version: '18'

      - name: Install dependencies
        run: npm install

      - name: Run tests
        run: npm test  # This assumes you have tests defined; replace this with actual test commands

  build:
    runs-on: ubuntu-latest
    needs: test  # This job will only run if tests pass

    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Set up Node.js
        uses: actions/setup-node@v2
        with:
          node-version: '18'

      - name: Install dependencies
        run: npm install

      - name: Build the app
        run: npm run build  # Replace this with your build process if applicable

  deploy:
    runs-on: ubuntu-latest
    needs: build  # Only deploy if the build succeeds

    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Deploy to Heroku
        uses: akhileshns/[email protected]
        with:
          heroku_api_key: ${{ secrets.HEROKU_API_KEY }}  # Heroku API key stored in GitHub secrets
          heroku_app_name: "your-heroku-app-name"  # Replace with your Heroku app name
          heroku_email: "[email protected]"

Explanation:

  • The on section specifies that this workflow should run whenever code is pushed to the main branch.
  • The test job installs dependencies and runs tests.
  • The build job depends on the test job and only runs if the tests pass. It installs dependencies and builds the app.
  • The deploy job deploys the app to Heroku, using the heroku-deploy GitHub Action. It only runs if the build succeeds.
See also  Part 8: Case Studies of Successful Cost and Performance Optimization on AWS

Step 4: Configure Secrets for Heroku Deployment

To securely deploy your app to Heroku, you’ll need to store your Heroku API key in GitHub Secrets.

  1. Generate a Heroku API key:
  • Go to your Heroku dashboard.
  • Click on your profile picture (top right) and go to Account Settings.
  • Under API Key, click Reveal API Key and copy it.
  1. Add the API key to GitHub Secrets:
  • Go to your GitHub repository.
  • Click on Settings -> Secrets and variables -> Actions -> New repository secret.
  • Add a secret called HEROKU_API_KEY and paste your Heroku API key.

Step 5: Trigger the CI/CD Pipeline

To test the CI/CD pipeline, make a small change to the code, commit, and push it to the main branch:

git add .
git commit -m "Trigger CI/CD pipeline"
git push origin main

Go to your GitHub repository, and you’ll see the workflow running under the Actions tab. You can view the logs for each job (test, build, deploy).

Once the workflow completes, the app will be automatically deployed to Heroku. You can visit your app’s Heroku URL to verify the deployment.


Step 6: Adding More Tests (Optional)

If you don’t have tests set up in your project yet, here’s a simple example for a Node.js app using Jest.

  1. Install Jest as a development dependency:
npm install jest --save-dev
  1. Add a test script in your package.json:
"scripts": {
  "test": "jest"
}
  1. Create a simple test in a test.js file:
touch test.js

Add the following test to test.js:

test('simple test', () => {
  expect(1 + 1).toBe(2);
});

Now, when you push changes to GitHub, the pipeline will run this test as part of the CI process.

See also  Part 8: Future Trends in Linux Server Optimization for Cloud Computing

Step 7: Deploying to AWS (Optional)

If you prefer deploying to AWS instead of Heroku, you can modify the deploy job in the GitHub Actions YAML file to use AWS CLI commands.

Here’s an example of deploying a Docker container to AWS Elastic Beanstalk:

deploy:
  runs-on: ubuntu-latest
  needs: build

  steps:
    - name: Checkout code
      uses: actions/checkout@v2

    - name: Configure AWS credentials
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: us-east-1

    - name: Deploy to Elastic Beanstalk
      run: |
        eb init your-app-name --platform node.js --region us-east-1
        eb deploy

Make sure to add your AWS credentials to GitHub Secrets and configure your Elastic Beanstalk environment.


Conclusion

In this tutorial, you learned how to build a cloud-native CI/CD pipeline using GitHub Actions. We created a simple workflow that tests, builds, and deploys your application to Heroku automatically whenever you push changes to your GitHub repository. GitHub Actions is incredibly flexible, and you can adapt this workflow to deploy to other cloud providers like AWS, Google Cloud, or Azure.

You can extend the pipeline further by adding more tests, integrating notifications, or building multiple environments (development, staging, production).

Feel free to copy the code and configuration to start automating your deployment process!

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.