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 Delivery Continuous Deployment
Every commit is deployable Every commit IS deployed
Manual deployment trigger Automatic deployment
Human approval gate Automated gates only
More common Requires 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

Technique Improvement
Parallel jobs 2-4x faster
Caching Saves dependency download time
Incremental builds Only rebuild changed
Slim base images Faster pull times
Test parallelization Scale 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?"

Metric Good Target Why It Matters
Build time < 10 min Developer productivity
Success rate > 95% Pipeline reliability
Deployment frequency Daily+ Delivery velocity
Lead time < 1 day Time to value
MTTR < 1 hour Recovery speed
Test coverage > 80% Quality confidence

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

Quiz

Module 3: CI/CD & Infrastructure as Code

Take Quiz