CI/CD & Infrastructure as Code

CI/CD Pipeline Design

4 min read

CI/CD pipeline questions test your understanding of modern software delivery. Let's cover what interviewers expect.

CI/CD Fundamentals

Continuous Integration (CI)

Developer → Commit → Build → Test → Integrate
                    Feedback (fast!)

CI Goals:

  • Detect integration issues early
  • Fast feedback (< 10 minutes ideal)
  • Automated testing
  • Consistent builds

Continuous Delivery vs Deployment

Continuous DeliveryContinuous Deployment
Every commit is deployableEvery commit IS deployed
Manual deployment triggerAutomatic deployment
Human approval gateAutomated gates only
More commonRequires mature testing

GitHub Actions Pipeline

name: CI/CD Pipeline

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'

      - name: Install dependencies
        run: pip install -r requirements.txt

      - name: Run tests
        run: pytest --cov=app tests/

      - name: Upload coverage
        uses: codecov/codecov-action@v4

  build:
    needs: test
    runs-on: ubuntu-latest
    outputs:
      image-tag: ${{ steps.meta.outputs.tags }}
    steps:
      - uses: actions/checkout@v4

      - name: Build image
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}

  deploy-staging:
    needs: build
    runs-on: ubuntu-latest
    environment: staging
    steps:
      - name: Deploy to staging
        run: |
          kubectl set image deployment/app \
            app=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}

  deploy-production:
    needs: deploy-staging
    runs-on: ubuntu-latest
    environment:
      name: production
      url: https://app.example.com
    steps:
      - name: Deploy to production
        run: |
          kubectl set image deployment/app \
            app=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}

GitLab CI Pipeline

stages:
  - test
  - build
  - deploy

variables:
  DOCKER_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA

test:
  stage: test
  image: python:3.11
  script:
    - pip install -r requirements.txt
    - pytest --cov=app tests/
  coverage: '/TOTAL.*\s+(\d+%)/'

build:
  stage: build
  image: docker:24.0
  services:
    - docker:24.0-dind
  script:
    - docker build -t $DOCKER_IMAGE .
    - docker push $DOCKER_IMAGE
  rules:
    - if: $CI_COMMIT_BRANCH == "main"

deploy_staging:
  stage: deploy
  environment:
    name: staging
  script:
    - kubectl set image deployment/app app=$DOCKER_IMAGE
  rules:
    - if: $CI_COMMIT_BRANCH == "main"

deploy_production:
  stage: deploy
  environment:
    name: production
  script:
    - kubectl set image deployment/app app=$DOCKER_IMAGE
  when: manual  # Manual approval required
  rules:
    - if: $CI_COMMIT_BRANCH == "main"

Pipeline Best Practices

Speed Optimization

TechniqueImprovement
Parallel jobs2-4x faster
CachingSaves dependency download time
Incremental buildsOnly rebuild changed
Slim base imagesFaster pull times
Test parallelizationScale with runners
# GitHub Actions caching example
- name: Cache pip packages
  uses: actions/cache@v4
  with:
    path: ~/.cache/pip
    key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
    restore-keys: |
      ${{ runner.os }}-pip-

Security in Pipelines

# Secrets management
env:
  AWS_ACCESS_KEY: ${{ secrets.AWS_ACCESS_KEY }}

# NEVER do this:
# AWS_ACCESS_KEY: AKIAXXXXXXXXXXXXXXXX

# Security scanning
- name: Run Trivy vulnerability scanner
  uses: aquasecurity/trivy-action@master
  with:
    image-ref: ${{ env.IMAGE }}
    format: 'sarif'
    severity: 'CRITICAL,HIGH'

Interview Questions

Q: "How would you design a CI/CD pipeline for 100 microservices?"

Key points to cover:

  1. Monorepo vs polyrepo: Affects how pipelines trigger
  2. Shared pipeline templates: Reduce duplication
  3. Service-specific overrides: When needed
  4. Parallel execution: Independent services build in parallel
  5. Dependency handling: Services that depend on each other
  6. Environment promotion: Dev → Staging → Prod
# Example: Shared template approach
.deploy_template:
  script:
    - deploy.sh $ENVIRONMENT
  rules:
    - if: $CI_COMMIT_BRANCH == "main"

deploy_service_a:
  extends: .deploy_template
  variables:
    SERVICE: service-a

Q: "What metrics do you track for CI/CD health?"

MetricGood TargetWhy It Matters
Build time< 10 minDeveloper productivity
Success rate> 95%Pipeline reliability
Deployment frequencyDaily+Delivery velocity
Lead time< 1 dayTime to value
MTTR< 1 hourRecovery speed
Test coverage> 80%Quality confidence

Next, we'll cover Infrastructure as Code with Terraform—essential for any DevOps/SRE role. :::

Quick check: how does this lesson land for you?

Quiz

Module 3: CI/CD & Infrastructure as Code

Take Quiz
FREE WEEKLY NEWSLETTER

Stay on the Nerd Track

One email per week — courses, deep dives, tools, and AI experiments.

No spam. Unsubscribe anytime.