top of page

What Is a Mock Safe Environment in CI/CD Pipelines?

Recently while working on a project where I had to deploy infrastructure on Azure using Terraform, Validate the deployment and then run the full CI/CD pipeline again and again. This had been an exhausting experience with:

  • Waiting for Terraform to provision resources,

  • Rebuilding environments from scratch,

  • Re-triggering API calls to Azure, and

  • Watching pipelines fail because of a small typo or a missing variable.


After the 10th failed run of the day, I realized I wasn’t testing my logic anymore, I was just testing the cloud’s patience.

That’s where I read the concept of mock runs and it changed the scenario for building and testing pipeline.


As DevOps or SRE professionals, we often equate “testing” with “deploying.”

But here’s what I understand is that every test doesn't require hitting live infrastructure.


When we are developing CI/CD automation, most of the time we are actually testing things like:

  • Directory structures and file paths

  • Environment variable handling

  • YAML syntax and naming conventions

  • Conditional logic in scripts

  • Basic workflow correctness


You don’t need an active cloud subscription to validate those.


Instead, you can design your pipelines to run in mock-safe mode — a mode where all cloud or external dependencies are simulated, allowing you to validate your logic safely and instantly. This helps when you are just doing any hands-on or project that doesn't need any real deployments, but you are still confident that your pipeline runs correctly when the actual deployment happens.


What Is a Mock-Safe Environment?

A mock-safe environment is a testing mode in CI/CD pipelines where all real external operations (like deploying infrastructure, fetching secrets, or calling APIs) are replaced by simulated, controlled, and safe operations.


In other words, your pipeline behaves like it’s deploying — but it never actually does, just like a simulator.

You get to test the whole pipeline (Logic), without risking the real (Production Cloud Environment).


How Mock Runs Work ?

Mock runs are essentially a controlled simulation of your CI/CD workflow. Instead of executing real-world operations like deploying infrastructure or fetching secrets, your scripts and pipeline pretend to do those actions while still executing your logic end-to-end. This ensures safe, fast, and repeatable tests.


Let’s break this down step by step.


Step 1: Add a Mock Mode Flag


The first key idea is to signal your scripts when to operate in mock mode. This is usually done via an environment variable like MOCK_RUN. Similar to scripting languages, you can use an environment variable to indicate whether the pipeline should perform a real deployment or a mock run.

export MOCK_RUN=true

In GitHub Actions or any CI/CD system, you can pass this variable to your pipeline:


env:
  MOCK_RUN: true

Why it matters:

  • Makes mock behavior configurable, so the same Terraform code can run in both simulation and real deployment modes.

  • Keeps CI/CD logic flexible across validation, staging, and production stages.


Step 2: Wrap External Actions in Conditional Logic


In Terraform pipelines, you can simulate deployments using the terraform plan command without applying changes. You can also use the mock flag to skip cloud resource creation altogether.


Example in a CI/CD step:


- name: Terraform Init & Plan
 run: |
    terraform init
    if [ "${MOCK_RUN}" = "true" ]; then
        echo "MOCK_RUN=true: Simulating deployment"
        terraform plan -out=tfplan
    else
        echo "Running actual deployment"
        terraform apply -auto-approve
    fi

Key points:

  • terraform plan generates a plan without provisioning resources.

  • terraform apply is only executed when MOCK_RUN=false.

  • This allows your CI/CD pipeline to validate Terraform configurations safely.



Step 3: Configure CI/CD Pipeline for Mock Runs

In CI/CD pipelines, mock mode is typically enabled for validation or pre-deployment stages. The pipeline runs through all Terraform steps except the real resource creation.


Example GitHub Actions job:


jobs:
 validate-terraform:
    runs-on: ubuntu-latest
    env:
      MOCK_RUN: true
    steps:
      - uses: actions/checkout@v4
      - name: Set up Terraform
        uses: hashicorp/setup-terraform@v2
        with:
          terraform_version: 1.5.5

      - name: Terraform Init & Plan
        run: |
          terraform init
          if [ "${MOCK_RUN}" = "true" ]; then
              echo "Simulating deployment with Terraform plan"
              terraform plan -out=tfplan
          else
              terraform apply -auto-approve
          fi

What happens here:

  • Mock mode runs terraform plan, generating a detailed plan without creating resources.

  • The pipeline executes end-to-end logic: initializing, planning, and logging outcomes.

  • No cloud credentials, API calls, or actual deployments are required.


Step 4: What Happens During a Mock Run


Behavior

Description

No actual resources created

Terraform only generates a plan (`terraform plan`) without provisioning.

No cloud credentials needed

Since no apply occurs, secrets or service principals are not required.

Full logic executes

All pre- and post-steps (validation, formatting, linting) run normally.

Fast iteration

CI feedback is instant because no real cloud operations are performed.


Step 5: Transition to Real Deployment


Once mock runs pass and your Terraform logic is validated:


env:
  MOCK_RUN: false
  • The pipeline executes terraform apply, provisioning real infrastructure.

  • Confidence is higher because the plan has already been verified.

  • CI/CD failures now reflect real deployment issues, not syntax or logic errors.


After implementing mock runs in my Terraform + Azure CI pipeline:

  • My iteration cycle dropped from 10–15 minutes per run to under 1 minute.

  • Failures became meaningful — related to logic, not infrastructure.

  • By the time I ran the real deployment, I knew my logic, structure, and flow were already correct.

  • As SREs and DevOps engineers, our job isn’t to deploy faster — it’s to deploy smarter. And sometimes, the smartest way to deploy… is to not deploy at all — until it’s absolutely necessary.


Sample GitHub Actions CI Pipeline: Mock-Safe Terraform Deployment:


name: Terraform CI/CD Pipeline

on:
  push:
    branches:
      - main
  pull_request:

env:
  # Default to mock run for safety; set to false for real deployments
  MOCK_RUN: true
  TF_WORKING_DIR: ./terraform

jobs:
  terraform-validate:
    name: Terraform Validate & Plan
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Repository
        uses: actions/checkout@v4

      - name: Set up Terraform
        uses: hashicorp/setup-terraform@v2
        with:
          terraform_version: 1.5.5

      - name: Terraform Init
        run: terraform -chdir=${{ env.TF_WORKING_DIR }} init -input=false

      - name: Terraform Validate
        run: terraform -chdir=${{ env.TF_WORKING_DIR }} validate

      - name: Terraform Plan / Mock Deployment
        run: |
          if [ "${MOCK_RUN}" = "true" ]; then
            echo "MOCK_RUN=true: Simulating deployment..."
            terraform -chdir=${{ env.TF_WORKING_DIR }} plan -out=tfplan
          else
            echo "MOCK_RUN=false: Executing real deployment..."
            terraform -chdir=${{ env.TF_WORKING_DIR }} apply -auto-approve
          fi

  terraform-lint:
    name: Terraform Lint & Format
    runs-on: ubuntu-latest
    needs: terraform-validate
    steps:
      - name: Checkout Repository
        uses: actions/checkout@v4

      - name: Terraform Format Check
        run: terraform -chdir=${{ env.TF_WORKING_DIR }} fmt -check

      - name: Terraform Lint (tflint)
        run: |
          curl -sSL https://raw.githubusercontent.com/terraform-linters/tflint/master/install_linux.sh | bash
          tflint -c tflint.hcl ${{ env.TF_WORKING_DIR }}

  post-processing:
    name: Post-Processing & Notifications
    runs-on: ubuntu-latest
    needs: [terraform-validate, terraform-lint]
    steps:
      - name: Send CI Status
        run: echo "Pipeline completed. MOCK_RUN=${{ env.MOCK_RUN }}"


How This Pipeline Implements Mock-Safe Mode

  1. Mock Run Flag


  • Controlled via env: MOCK_RUN.

  • By default, it’s true to simulate deployments safely.


2. Conditional Terraform Execution

  • Uses terraform plan in mock mode (safe, fast, no real resources).

  • Uses terraform apply only when MOCK_RUN=false.


3. Full CI Logic Without Cloud Risk

  • Validation, linting, and formatting all run even in mock mode.

  • Quick feedback on YAML, paths, environment variables, and workflow correctness.


4. Transition to Real Deployment

  • Simply set MOCK_RUN=false in the workflow environment variables.

  • The pipeline runs the same logic, but provisions real resources confidently.

What Is a Mock-safe Environment

Comments


bottom of page