Managing Configuration on Git

By integrating with Bricks Action, teams can "shift-left" infrastructure provisioning and maintain PR-based workflows, leveraging developer-friendly and GitOps-compatible declarative files.

Below is a suggested opinionated workflow that can be modified according to the team's needs.

  1. Developers leverage side branches to provision their infrastructure. Each commit triggers a deployment to a developer-owned environment

  2. Once the changes are ready, the engineer opens a Pull Request (PR) to promote the change for review and obtain approval before merging and deploying to shared environments.

  3. Once the Pull Request (PR) is approved, the engineer merges its code and waits for the next release day.

  4. On the release day, the DevOps team should trigger a workflow that detects the recent changes and creates a batch deployment.

Batch Deployments

Bluebricks recommends aligning infrastructure modifications with the primary SDLC.

On release day, the Delivery team manually triggers or automates a workflow using a ticketing system; the GitHub Action Workflow should collect the recent changes and trigger installation for each.

This approach ensures:

  1. Synchronized application and infrastructure releases.

  2. Controlled, predictable, and repeatable deployments.

  3. Automation-driven efficiency with minimal manual intervention.

Github Action Workflow Example

name: Bricks Matrix Deployment Workflow

on:
  pull_request:
    branches: [master]
    paths:
      - 'bluebricks/environments/**'
  push:
    branches:
      - master
      - feature/inf-273/deployments
    paths:
      - 'bluebricks/environments/**'
  workflow_dispatch:
    inputs:
      plan_only:
        description: 'Generate plan only without deploying'
        required: true
        default: true
        type: boolean

jobs:
  # Detect changes in deployments folder and prepare matrix
  changes:
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.set-matrix.outputs.matrix }}
      any_changes: ${{ steps.set-matrix.outputs.any_changes }}
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          fetch-depth: 0  # Fetch all history for detecting changes

      - name: Get changed files
        id: changed-files
        # For PRs use git diff, for manual runs find all YAML files
        run: |
          if [[ "${{ github.event_name }}" == "pull_request" ]]; then
            # Get changed files in PR
            CHANGED_FILES=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.sha }} -- bluebricks/environments/ | grep -v values.yaml | grep -E '\.ya?ml$' || echo "")
          else
            # For workflow_dispatch, consider all YAML files
            CHANGED_FILES=$(find bluebricks/environments -type f \( -name "*.yaml" -o -name "*.yml" \) ! -name "values.yaml" | sort)
          fi
          echo "Files to process:"
          echo "$CHANGED_FILES"
          {
            echo "CHANGED_FILES<<EOF"
            echo "$CHANGED_FILES"
            echo "EOF"
          } >> "$GITHUB_ENV"

      - name: Set matrix
        id: set-matrix
        run: |
          # Convert changed files to JSON array format
          if [[ -z "$CHANGED_FILES" ]]; then
            echo "No deployment files changed"
            echo "matrix=[]" >> $GITHUB_OUTPUT
            echo "any_changes=false" >> $GITHUB_OUTPUT
          else
            # Convert space separated file list to JSON array
            FILES_JSON=$(echo "$CHANGED_FILES" | jq -R -s -c 'split("\n") | map(select(length > 0))')
            echo "matrix=${FILES_JSON}" >> $GITHUB_OUTPUT
            echo "any_changes=true" >> $GITHUB_OUTPUT
          fi

  # Create deployment plans for all changed files
  bricks-plan:
    needs: changes
    if: needs.changes.outputs.any_changes == 'true'
    runs-on: ubuntu-latest
    strategy:
      matrix:
        file: ${{ fromJson(needs.changes.outputs.matrix) }}
      # Allow other deployments to continue even if one fails
      fail-fast: false
      # Limit parallel executions to avoid rate limiting
      max-parallel: 5
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Extract deployment name
        id: extract-name
        run: |
          # Extract deployment name from file path for use in job display
          FILENAME=$(basename "${{ matrix.file }}")
          DEPLOYMENT_NAME=${FILENAME%.*}  # Remove extension
          echo "name=$DEPLOYMENT_NAME" >> $GITHUB_OUTPUT

      - name: Create Bricks deployment plan (${{ steps.extract-name.outputs.name }})
        uses: bluebricks-co/bricks-action@support-for-install-flow
        with:
          command: install
          file: ${{ matrix.file }}
          # env: ${{ github.event.inputs.environment || 'staging' }}
          plan-only: ${{ github.event.inputs.plan_only || 'true' }}
          api-key: ${{ secrets.BRICKS_API_KEY }}

  # Deploy if workflow_dispatch and plan_only is false
  bricks-deploy:
    needs: [changes, bricks-plan]
    if: |
      needs.changes.outputs.any_changes == 'true' && 
      github.event_name == 'workflow_dispatch' && 
      github.event.inputs.plan_only == 'false'
    runs-on: ubuntu-latest
    strategy:
      matrix:
        file: ${{ fromJson(needs.changes.outputs.matrix) }}
      fail-fast: false
      max-parallel: 3
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Extract deployment name
        id: extract-name
        run: |
          FILENAME=$(basename "${{ matrix.file }}")
          DEPLOYMENT_NAME=${FILENAME%.*}
          echo "name=$DEPLOYMENT_NAME" >> $GITHUB_OUTPUT

      - name: Execute Bricks deployment (${{ steps.extract-name.outputs.name }})
        uses: bluebricks-co/bricks-action@support-for-install-flow
        with:
          command: install
          file: ${{ matrix.file }}
          api-key: ${{ secrets.BRICKS_API_KEY }}

  summary:
    needs: [changes, bricks-plan]
    if: always() && needs.changes.outputs.any_changes == 'true'
    runs-on: ubuntu-latest
    steps:
      - name: Deployment Summary
        run: |
          echo "### Deployment Summary" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "Processed deployment files:" >> $GITHUB_STEP_SUMMARY
          
          # Use a more reliable approach that avoids complex JSON parsing
          matrix='${{ needs.changes.outputs.matrix }}'
          # Method 1: Simple approach that works even if JSON is malformed
          echo "$matrix" | grep -o '"[^"]*"' | sed 's/"//g' | while read file; do
            echo "- $file" >> $GITHUB_STEP_SUMMARY
          done
          
          # Method 2 (Fallback): If nothing was listed above
          if ! grep -q "^-" $GITHUB_STEP_SUMMARY; then
            echo "- No files were processed or could not parse file list" >> $GITHUB_STEP_SUMMARY
          fi

Last updated

Was this helpful?