AZ-400: Designing and Implementing Microsoft DevOps Solutions

Design and Implement Pipelines

Deployment Automation with GitHub Actions

In this article, we explore how to automate deployments using GitHub Actions. We'll deploy a Node.js application to Azure—a scenario that represents real-world CI/CD implementations and is also relevant to the AZ-400: Designing and Implementing Microsoft DevOps Solutions exam. Our sample application is the KodeKloud copy shop running on your screen. With stakeholder approval, the website is ready to be deployed to Azure.

We'll cover the complete process—from setting up a GitHub Actions workflow to deploying your application on Azure.


Setting Up the Workflow

GitHub Actions uses workflows defined in YAML files stored in the repository’s .github/workflows directory. You can create a new YAML file or navigate to the Actions tab in your repository to get started.

The image shows a GitHub repository page for "KodeKloudCoffee," featuring a list of files and a README section describing a coffee shop website project. The repository includes various files and commits, with details about languages used and suggested workflows.

While the Actions tab offers several pre-built workflows, we will manually build one to gain a better understanding of each step.


Workflow Structure Overview

Below is a basic GitHub Actions workflow configuration for our Node.js application. This workflow is triggered on pushes to the main branch and runs on the latest Ubuntu runner:

name: Deploy to Azure
on:
  push:
    branches: [ main ]
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:

Understanding GitHub Actions Events

The on section in the YAML config specifies the events that trigger the workflow. In our example, a push to the main branch starts the workflow. GitHub Actions supports a variety of events, such as pull requests and scheduled events using cron syntax:

name: Deploy to Azure
on:
  schedule:
    - cron: '*/15 * * * *'
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:

For this demo, we rely on the push event.

Jobs and Steps

Workflows consist of jobs, each running in a fresh virtual environment. Every job comprises several steps, which can execute commands or run pre-built actions. In the following snippet, the steps include checking out the repository, setting up Node.js, installing dependencies, building the project, and running tests:

name: Deploy to Azure
on:
  push:
    branches: [ main ]
jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Use Node.js
        uses: actions/setup-node@v2
        with:
          node-version: '14.x'
      - run: npm install
      - run: npm run build --if-present
      - run: npm test

These modular actions, available from both GitHub and the community, help streamline common tasks in your deployment pipeline.


Enhancing the Workflow with Environment Variables and Upgraded Actions

To better support custom deployments, we update the workflow with environment variables and manual triggers using workflow_dispatch. Additionally, these variables allow you to parameterize your build and deployment configuration.

name: Deploy to Azure
on:
  push:
    branches: [ main ]
  workflow_dispatch:

env:
  AZURE_WEBAPP_NAME: kodekloudcoffee
  AZURE_WEBAPP_PACKAGE_PATH: '.'
  NODE_VERSION: '20.x'

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Use Node.js
        uses: actions/setup-node@v2
        with:
          node-version: '14.x'
      - run: npm install
      - run: npm ci
      - run: npm run build --if-present
      - run: npm test

Manual Trigger

The workflow_dispatch event enables manual execution of the workflow directly from the GitHub Actions interface.

Next, we refine our workflow by separating the build and deploy jobs. This separation ensures that deployment only occurs after a successful build.

name: Deploy to Azure
on:
  push:
    branches: [ main ]
  workflow_dispatch:

env:
  AZURE_WEBAPP_NAME: kodekloudcoffee
  AZURE_WEBAPP_PACKAGE_PATH: '.'
  NODE_VERSION: '20.x'

permissions:
  contents: read

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: 'npm'
      - name: npm install, build, and test
        run: |
          npm install
          npm run build --if-present
          npm test
      - name: Upload artifacts
        uses: actions/upload-artifact@v3
        with:
          name: node-app
          path: .

  deploy:
    permissions:
      contents: none
    runs-on: ubuntu-latest
    needs: build
    environment:
      name: 'Development'
      url: ${{ steps.deploy-to-webapp.outputs.webapp-url }}
    steps:
      - name: Download artifacts from build
        uses: actions/download-artifact@v3
      - name: Deploy to Azure WebApp
        id: deploy-to-webapp
        uses: azure/webapps-deploy@v2
        with:
          app-name: ${{ env.AZURE_WEBAPP_NAME }}
          publish-profile: ${{ secrets.AZURE_WEBAPP_PUBLISH_PROFILE }}
          package: ${{ env.AZURE_WEBAPP_PACKAGE_PATH }}

In this configuration:

  • The build job checks out the code, prepares the Node.js environment (with caching), installs dependencies, builds the project, runs tests, and uploads the build artifacts.
  • The deploy job downloads the artifacts and uses a pre-built GitHub Action to deploy your application to Azure. The needs: build keyword ensures that the deploy job only runs after a successful build.

Setting Up Your Azure Web App

Before deploying your application, create a web app in the Azure portal:

  1. Log in to the Azure portal and navigate to App Services.
  2. Create a new Web App:
    • Select your subscription and resource group.
    • Name the web app (e.g., "KodeKloudCoffee").
    • Choose “Publish: Code” and select the Node.js runtime.
    • Set the region (e.g., Central US) and select Linux as the operating system.
    • Choose a free plan if applicable.
  3. Configure the deployment settings. Note that GitHub Actions auto-configuration for Windows deployments is not supported with manual workflows.
  4. Enable basic authentication if required.
  5. Complete the review and creation process.

The image shows the Microsoft Azure portal homepage, displaying various Azure services, resources, navigation options, and tools. It includes sections for creating resources, managing subscriptions, and accessing documentation.

The image shows a Microsoft Azure portal page for creating a web app, with options for instance details, runtime stack, operating system, region, and pricing plans.

After setting up the web app, navigate to its resource page and download the Publish Profile. Store this file securely; you'll use it later by adding it as a repository secret.

Security Notice

Never commit your Publish Profile directly to your repository. Always store sensitive credentials as encrypted GitHub Secrets.

If desired, the Azure portal offers GitHub integration settings (currently optimized for Windows deployments), but for this demo, we continue with our custom workflow.

The image shows a Microsoft Azure portal page for creating a web app, with options for configuring GitHub settings and continuous deployment.

Double-check that basic authentication is enabled along with the correct networking and monitoring configurations.

The image shows a Microsoft Azure portal page for creating a web app, displaying details such as subscription, resource group, and app service plan. The configuration includes a free SKU, Node 20 LTS runtime stack, and basic authentication enabled.

Once your Azure web app is configured, commit your changes to the main branch to trigger the GitHub Actions workflow.


Configuring GitHub Secrets and Final Deployment

Before the workflow can deploy your application to Azure, add the Publish Profile as a repository secret:

  1. Go to your repository’s SettingsSecrets and variablesActions.
  2. Create a new repository secret named "AZURE_WEBAPP_PUBLISH_PROFILE" and paste the content of your downloaded Publish Profile.

Once the secret is added and changes have been pushed, the workflow will run automatically. In the GitHub Actions interface, you should see two jobs: the build job and the deploy job. The deploy job will only initiate once the build job finishes without errors.

The image shows a GitHub Actions workflow page for a project named "KodeKloudCoffee," displaying the successful completion of a build job with detailed steps and logs.

The image shows a GitHub Actions interface displaying the successful completion of a deployment workflow, including steps like setting up the job, downloading artifacts, and deploying to Azure WebApp.

After deployment, review the deployment logs in the Azure portal to ensure your website is running correctly.

The image shows the Microsoft Azure portal interface for a web app named "kodekloudcoffee," displaying its overview, properties, and deployment details.


Conclusion

In this article, we set up a streamlined CI/CD pipeline using GitHub Actions to deploy a Node.js application to an Azure App Service. Here's a quick recap of what we covered:

  • We configured a workflow triggered by pushes to the main branch and allowed for manual triggering via workflow_dispatch.
  • The build job checked out the repository, set up Node.js, installed dependencies, built the project, ran tests, and uploaded artifacts.
  • The deploy job downloaded these artifacts and deployed them to Azure, ensuring a structured flow by using the needs keyword.
  • GitHub Secrets were used to securely store the Azure Publish Profile.
  • Key GitHub Actions concepts such as jobs, steps, environment variables, and dependency management were demonstrated.

GitHub Actions simplifies many aspects of your development workflow, providing a robust platform for automating deployments. Familiarity with these configurations is also beneficial for those preparing for the AZ-400: Designing and Implementing Microsoft DevOps Solutions exam.

Happy deploying!

Watch Video

Watch video content

Previous
Demo Azure Pipelines