Skip to content

Lesson 3: Continuous Compliance (AWS Config & Security Hub) & Zero-Downtime PDBs

🧠 The Concept (Explain Like I'm 5)

  • The Manual Audit (The Old Nightmare): Once a year, auditors from SOC 2 or ISO 27001 show up with clipboards. Engineers spend 3 months taking screenshots of the AWS Console to prove S3 buckets are encrypted.
  • Continuous Compliance (The Automated CCTV): AWS Config is a camera watching every AWS resource 24/7. The moment an engineer unchecks "Enable Encryption", AWS Config sounds an alarm, sends an alert to Security Hub, and can even automatically re-encrypt the bucket (Automated Remediation).
  • PodDisruptionBudgets (PDBs): A legally binding union contract between your microservices and Kubernetes. A PDB says: "You can terminate my worker nodes for patching whenever you want, BUT you must guarantee that at least 2 out of my 3 payment replicas remain alive and serving traffic at every microsecond!"

🏒 The Enterprise Context

  • ISO 27001 & SOC 2 Type II: Requires proving that security controls are effective continuously over time (not just on the day of the audit).
  • AWS Config Conformance Packs: Pre-packaged collections of dozens of AWS Config rules mapped directly to compliance standards (e.g., Operational-Best-Practices-for-CIS-AWS-Foundations-Benchmark).
  • Karpenter AMI Drifting: When your Packer pipeline publishes a new hardened Golden AMI, you don't run manual scripts. Karpenter detects that the running nodes have an AMI ID different from the latest EC2NodeClass definition and drifts the nodes gracefully while respecting PDBs!

πŸ—ΊοΈ Visual Architecture: Continuous Compliance & Automated Node Drift

flowchart TD
    subgraph CompliancePipeline ["Continuous Compliance Monitoring"]
        CloudTrail["AWS CloudTrail (API Events)"] --> AWSConfig["<b>AWS Config Engine</b><br/>(CIS Benchmark Conformance Pack)"]
        AWSConfig -->|Non-Compliant Resource Detected| SecHub["<b>AWS Security Hub</b><br/>(Aggregated Compliance Score)"]
        SecHub --> EventBridge["Amazon EventBridge"]
        EventBridge --> RemediationLambda["Automated Remediation Lambda<br/>(Re-enables Encryption / Disables Public IP)"]
    end

    subgraph NodeDriftPipeline ["Karpenter AMI Drift & PDB Protection"]
        PackerAMI["New Golden AMI Published"] --> Karpenter["Karpenter Controller"]
        Karpenter -->|Detects AMI Drift| CheckPDB{"Check PodDisruptionBudget:<br/>MinAvailable = 2?"}
        CheckPDB -->|PDB Satisfied| CordonDrain["Cordon & Graceful Drain Old Node"]
        CordonDrain --> NewNode["Launch New Node with Golden AMI"]
    end

πŸ’» Production Code: PodDisruptionBudget & AWS Config Conformance Pack

1. Production PodDisruptionBudget Manifest (pdb.yaml)

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: payment-service-pdb
  namespace: workloads
spec:
  minAvailable: 2 # At least 2 replicas must remain ready during node draining
  selector:
    matchLabels:
      app: payment-service

2. High-Availability Deployment with PreStop Graceful Termination Hook

apiVersion: apps/v1
kind: Deployment
metadata:
  name: payment-service
  namespace: workloads
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: payment-service
    spec:
      terminationGracePeriodSeconds: 60 # Give in-flight transactions 60s to finish
      containers:
        - name: app
          image: 123456789012.dkr.ecr.us-east-1.amazonaws.com/payment:v1.0.0
          lifecycle:
            preStop:
              exec:
                # Sleep 15s to allow ALB health checks to deregister pod before process stops
                command: ["/bin/sh", "-c", "sleep 15"]
          readinessProbe:
            httpGet:
              path: /healthz
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 5

3. AWS Config Conformance Pack in Terraform

resource "aws_config_conformance_pack" "cis_foundations" {
  name = "Operational-Best-Practices-for-CIS-AWS-Benchmark"

  template_s3_uri = "s3://aws-config-conformance-packs-us-east-1/Operational-Best-Practices-for-CIS-AWS-Foundations-Benchmark.yaml"

  input_parameter {
    parameter_name  = "AccessKeysRotatedParamMaxAccessKeyAge"
    parameter_value = "90"
  }
}