Skip to content

6.6. CI/CD

CI/CD stands for Continuous Integration and Continuous Deployment.

At its core, CI/CD is about automating the steps carried out manually in the previous sections, improving the way code is built, tested, and deployed, so that changes flow smoothly from development to production without the delays, risks, and manual effort of traditional release processes.

In pricing and analytics teams, this can be especially powerful: instead of emailing around scripts, copying models into spreadsheets, or manually updating rating engines, CI/CD provides a repeatable, controlled pipeline to move from development to production safely.


Why use CI/CD?

  • Automation – reduces manual steps in testing and deployment
  • Reliability – ensures changes meet quality standards before going live
  • Speed – faster turnaround from code changes to production impact
  • Collaboration – allows multiple analysts/developers to work on the same codebase without chaos
  • Auditability – provides a clear trail of what was changed, tested, and deployed
  • Safety – deployments are consistent, reducing the risk of errors from copy-paste or manual updates

Continuous Integration (CI)

Continuous Integration is about bringing together code from multiple contributors in a controlled way.

  • Every time code is committed, automated tests run to check that nothing is broken
  • Teams can spot integration issues early rather than discovering them weeks later
  • Code quality tools (e.g. linting, formatting, type checks) can be included in the pipeline
  • For analytics: data quality checks and model validation tests can be built into CI

Example in Pricing:
Every time an analyst updates a rating factor transformation script, CI runs unit tests to confirm outputs (e.g. age banding logic) still work correctly, and that the model still trains and scores without error.


Continuous Deployment (CD)

Continuous Deployment automates the process of moving changes through testing environments and into production.

  • After review and approval, code is automatically deployed to a production environment
  • Reduces the time between developing a change and making it available to end users
  • Ensures deployments are consistent every time, rather than relying on manual steps

Example in Pricing:
When a new GLM model is approved, CD could automatically:
- Deploy the model to a staging environment for user acceptance testing - If approved, push it into the rating engine or API used in production
- Trigger monitoring dashboards to start tracking the model’s performance


Tools

There are many tools to support CI/CD. Common ones include:

  • GitHub Actions – integrates directly with GitHub for automation
  • Azure DevOps – widely used in enterprises, integrates with Microsoft’s cloud
  • GitLab CI/CD – a strong open-source alternative
  • Jenkins – a flexible, older but still widely used tool

Extensions for Analytics & Pricing

In addition to the standard software engineering practices, analytics teams can extend CI/CD to:

  • Data pipeline validation – ensure new code doesn’t break ETL or data extraction processes
  • Model validation – automatically check calibration, Gini, lift, or other key metrics before deployment
  • Impact analysis checks – simulate the effect of rating changes and ensure they are within expected ranges before approval
  • Security scanning – make sure dependencies and packages used are free of known vulnerabilities
  • Documentation updates – automatically build and publish documentation (e.g. model cards, assumptions, change logs)

Example Github Actions

name: CI/CD FastAPI to Azure

on:
  push:
    branches:
      - main
  workflow_dispatch:

env:
  IMAGE_NAME: pricing-app
  RESOURCE_GROUP: demo-fastapi
  CONTAINER_APP: pricingdemo-fastapi
  ACR_NAME: pricingdemofastapiregistry
  LOCATION: "UK South"

jobs:
  deploy:
    runs-on: ubuntu-latest
    defaults:
      run:
        shell: bash

    steps:
      # -------------------------
      # Checkout code
      # -------------------------
      - name: Checkout code
        uses: actions/checkout@v3

      # -------------------------
      # Setup Python
      # -------------------------
      - name: Setup Python
        uses: actions/setup-python@v4
        with:
          python-version: "3.12"

      # -------------------------
      # Setup Terraform
      # -------------------------
      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v2
        with:
          terraform_version: 1.8.0

      # -------------------------
      # Azure Login
      # -------------------------
      - name: Azure Login
        uses: azure/login@v1
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}

      # -------------------------
      # Terraform Init
      # -------------------------
      - name: Terraform Init
        run: terraform init

      # -------------------------
      # Terraform Plan
      # -------------------------
      - name: Terraform Plan
        run: terraform plan -out=tfplan -input=false

      # -------------------------
      # Terraform Apply
      # -------------------------
      - name: Terraform Apply
        run: terraform apply -auto-approve tfplan

      # -------------------------
      # Set Docker Image Tag based on commit SHA
      # -------------------------
      - name: Set Docker image tag
        run: echo "IMAGE_TAG=$(echo $GITHUB_SHA | cut -c1-7)" >> $GITHUB_ENV

      # -------------------------
      # Build Docker image
      # -------------------------
      - name: Build Docker image
        run: |
          docker build -t ${{ env.ACR_NAME }}.azurecr.io/${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }} .

      # -------------------------
      # Login to ACR
      # -------------------------
      - name: Login to Azure Container Registry
        run: |
          az acr login --name ${{ env.ACR_NAME }}

      # -------------------------
      # Push Docker image to ACR
      - name: Push Docker image
        run: |
          docker push ${{ env.ACR_NAME }}.azurecr.io/${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }}

      # -------------------------
      # Update Container App image
      # -------------------------
      - name: Update Container App
        run: |
          az containerapp update \
            --name ${{ env.CONTAINER_APP }} \
            --resource-group ${{ env.RESOURCE_GROUP }} \
            --image ${{ env.ACR_NAME }}.azurecr.io/${{ env.IMAGE_NAME }}:${{ env.IMAGE_TAG }}