Musings from the Scribes

Streamlining Environment Provisioning for Startups with GitHub Actions Matrix Jobs

Written by Leigh Shayler | Aug 30, 2024 7:11:15 AM

Many startups today face a struggle to find a working solution to provide white-labelled solutions for their customers. One common issue is managing a dynamic set of environments without incurring significant overhead each time a new one is added. In this blog post, we'll explore how startups can leverage GitHub Actions, specifically using matrix jobs and GitHub Environments, to streamline this process and maintain efficiency.

The Challenge

As a startup grows, so does its customer base. Each customer often requires a dedicated environment, tailored to their specific needs. However, provisioning and managing these environments can quickly become cumbersome, especially when new customers are onboarded regularly. Traditional methods might require significant manual intervention, leading to increased effort and potential errors.

The Solution: GitHub Actions Matrix Jobs & Environments

To address this challenge, we propose a solution that integrates seamlessly with your existing Continuous Integration/Continuous Deployment (CI/CD) processes using GitHub Actions. By storing an array of customers as a repository-level environment variable and utilizing matrix jobs in GitHub Actions, you can dynamically manage multiple environments with minimal effort.

Step-by-Step Implementation

1. Define a Repository-Level Environment Variable

Store an array of customer environments as a repository-level environment variable. This variable will act as the source of truth for your environments and can be accessed in the workflow configuration. In this case we are creating a list of three customers (customera, customerb, customerc).

You can do this from your repository settings.
https://github.com/<organisation>/<repository>/settings/variables/actions

2. Set Up a Matrix Job in GitHub Actions

Next we will set up a new GitHub action and use this environment variable as input for a matrix job in your GitHub Actions workflow. Matrix jobs allow you to run a job for each item in a matrix, in this case, for each customer environment.

# This is a basic workflow that is manually triggered
name: Manual workflow

on:
  workflow_dispatch:

jobs:
  test:
    strategy:
      matrix:
        environment: $
    runs-on: ubuntu-latest
    environment: $
    steps:
      - name: Display matrix and index
        run: |
          echo "Running on $
          echo "Environment Var #$"       
          # Add your build and deploy scripts here

Now, when we run our workflow now, we will see that we will get a new job scheduled for each deployment.

The useful part is where we use environment $. This allows us to provide each job with an environment with dedicated configuration and secrets.

3. Add environment specific configuration

To have get environment configured appropriately, we need to add environment level configuration using GitHub environment secrets and variables. Let’s add an environment for each of the customers (customera, customerb, customerc) from Step 1.

You can to this from your repository settings:
https://github.com/<organisation>/<repository>/settings/environments

For each of the environments you can add the required configuration or secrets, in this case we will add a single environment variable containing the customer name to demonstrate the configuration.

4. Check our progress

Now if we run the workflow within GitHub Actions, we can see that it runs a job for each customer and will print the customer name for each environment.

5. Add a new customer environment

Now for the great part. When we need to a new customer environment, we simply update the repository-level environment variable with the new customer environment and create the new GitHub environment and you can provision a new customer with zero code changes.

Next Steps

Hopefully this helps show an easy approach to supporting dynamic environments with GitHub Actions and Matrix Jobs. Combine this with the following to take it further:

  • Enable Environment Approvals in GitHub to provide control over when environment jobs run.

  • Leverage the GitHub Terraform provider to update this configuration if you have it stored elsewhere.

Source Code

Just want a working copy? Then fork our GitHub repository.