Cloud Modernization Patterns Module 6 · Stay Modern

Policy as Code and Drift Detection

Last reviewed

Intermediate

What you'll learn

~20 min
  • Gate pipelines on policy scans that fail hard, with a skip list that is documented and empty
  • Express compliance as data inherited through the baseline, annotated by control ID
  • Run drift detection as a scheduled pipeline citizen, and treat drift as an incident with a cause

From “we reviewed it” to “the pipeline enforces it”

Module 4 hardened one application. This lesson hardens the process — because at AI speed, the volume of infrastructure and code flowing toward production exceeds what any review meeting can hold. DevSecOps adoption, concretely, is three mechanisms: policy scans that gate, compliance expressed as inherited data, and drift detection that runs on a clock. All three are pipeline citizens; none is a quarterly meeting.

Mechanism 1: the hard-fail gate

Every infrastructure change passes a policy scanner in CI — checking encryption posture, network exposure, identity wiring, logging — and the gate’s configuration is where the discipline lives:

policy_gate:
fail_on: [CRITICAL, HIGH] # not "warn on" - FAIL on
skip_list: [] # exists, is reviewed, and is EMPTY
skip_policy: every entry requires - the finding ID, the reason, an
expiry date, and a decisions-register link. No permanent
skips. An entry without an expiry is a build failure itself.

The empty-but-documented skip list is the tell of a healthy gate. A gate with no skip mechanism gets disabled entirely the first time it blocks a genuine emergency (“just turn the scanner off for this release”); a gate with an undisciplined skip list becomes a suppression graveyard where every finding eventually retires. The narrow door — expiring, justified, register-linked skips — keeps the gate strict and survivable. The same shape applies to dependency scanning and the Lesson 6.1 no-stored-secrets guard: one pattern, every gate.

Mechanism 2: compliance as inherited data

Lesson 6.2’s baseline-plus-diff hierarchy was built for exactly this payload. The controls your framework requires are not a spreadsheet reviewed annually — they are the strict defaults in the baseline, annotated with the control IDs they satisfy:

config/baseline.yaml (excerpt)
storage:
public_network_access: Disabled # AC-4, SC-7
min_tls_version: "1.2" # SC-8, SC-13 - the floor; prefer 1.3
soft_delete_days: 90 # CP-9
logging:
diagnostic_settings: all-to-central # AU-2, AU-6, AU-12
retention_days: 365 # AU-11
identity:
local_auth: Disabled # IA-2 - directory identity only

Three payoffs. Every stack inherits the controls unless it visibly diffs away from one — and that diff is a reviewable line, not a forgotten checkbox. The annotations make “which stacks satisfy AU-11 and how?” a grep, not an archaeology project. And the same annotations are the raw material Lesson 6.4 compiles into accreditation evidence — write the control ID once, harvest it everywhere.

Mechanism 3: drift detection on a clock

The gate checks what flows through the pipeline. Drift detection catches what changed around it: the emergency portal edit at 2 a.m., the setting a vendor support session toggled, the resource someone created by hand. A scheduled pipeline — nightly is typical — compares deployed reality against declared state and files the differences:

Drift run, nightly:
compare: deployed state vs declared state, per stack
output: drift report - resource, expected, actual, first-seen
action: file as incident-class work. NEVER auto-revert blindly:
drift has a CAUSE. The 2 a.m. edit that kept dispatch alive
is a missing declaration to adopt into code; the mystery
change is a possible compromise to investigate. Reverting
first destroys the evidence either way.

Treat “why did this drift?” as the actual question. Adopted-into-code and investigated-then-reverted are both good outcomes; silent divergence — the state Lesson 6.2’s copies decayed into — is the only bad one. Drift volume is also a health metric: a stack that drifts weekly has a process problem upstream of any single incident (usually: the paved road is missing a capability people need at 2 a.m.).

💡AI on both sides of the gate

The same AI CLI that generates infrastructure at volume also triages at volume: “cluster tonight’s drift report by likely cause; draft the declaration-adoption PR for the dispatch change; flag anything touching identity or network for human review first” is a standing prompt. The gates stay deterministic — scanners and schedules, not model judgment — while AI absorbs the toil the gates produce. Machines gate; agents triage; humans decide the identity- and network-touching cases. That division holds up across the whole training: it is Lesson 5.2’s review table wearing ops clothes.

KNOWLEDGE CHECK

The policy gate blocks Friday's release: a HIGH finding on a storage account exposed to a vendor's IP range, needed for a weekend data exchange. The lead proposes setting fail_on to [CRITICAL] 'until Monday.' What does the mechanism say?

Key takeaway

Three pipeline citizens carry DevSecOps at scale: gates that fail hard with a documented, expiring, near-empty skip list; compliance as control-annotated defaults inherited through the baseline; and scheduled drift detection that treats every divergence as a question with a cause. Deterministic mechanisms gate, agents triage the volume, humans judge the sensitive residue — and Lesson 6.4 turns the whole apparatus into accreditation evidence.

Search lessons