Skip to content

Repository Architecture

This document explains the structure and conventions of the cloud certification study guides repository. Read it before contributing or making non-trivial changes.


At a glance

This repo is a markdown knowledge base for cloud + AI learning - certifications, hands-on patterns, plain-English concepts, and a beginner on-ramp. There is no build step, no test suite, no deployment - it is a content repository served as Markdown via GitHub.

cloud-data-ai-security-zero-to-hero/
β”œβ”€β”€ README.md           # Top-level overview + pillars + provider table
β”œβ”€β”€ STUDY-HUB.md        # Navigation hub: decision tree, career tracks, full provider table
β”œβ”€β”€ CLAUDE.md           # Project context for Claude Code / AI tools
β”œβ”€β”€ CONTRIBUTING.md     # How to contribute (templates, doc-link format, PR checklist)
β”œβ”€β”€ CHANGELOG.md        # User-visible / operationally-significant changes
β”œβ”€β”€ .templates/         # Cross-cert resources hubs (resources-aws.md, resources-azure.md, resources-gcp.md)
β”œβ”€β”€ assets/diagrams/    # PNG diagrams (draw.io exports), organized by topic subdir
β”œβ”€β”€ docs/               # Repo docs: ARCHITECTURE.md, certs.json (generated index), freshness.md, tag-taxonomy.md, improvement-roadmap.md
β”œβ”€β”€ exams/              # All certification study guides, organized by provider
β”œβ”€β”€ learn/              # Plain-English learning content for non-cert students
β”‚   β”œβ”€β”€ concepts/       # Bite-size topic pages (5-10 min reads): cloud + AI primitives
β”‚   β”œβ”€β”€ day-one/        # Strict beginner on-ramp (terminal, git, HTTP, servers)
β”‚   β”œβ”€β”€ ai-from-scratch.md
β”‚   β”œβ”€β”€ cloud-from-scratch.md
β”‚   β”œβ”€β”€ glossary.md
β”‚   └── youtube.md
└── resources/          # Cross-cert resources (roadmaps, comparisons, CLI cheat sheets, etc.)

exams/ - cert study guides

Directory structure

exams/<provider>/<cert-slug>/ (or exams/aws/<tier>/<cert-slug>/ for AWS, which uses an extra tier subdirectory).

Provider naming

Use the lowercase, hyphen-free provider name when possible:

  • aws, azure, gcp, kubernetes, nvidia, anthropic, hashicorp, databricks, snowflake, github, redhat, cisco, confluent, mongodb, finops, comptia, isc2, cloud-security-alliance, linux-foundation, oracle, ibm

AWS tier subdirectories

AWS uses an extra layer because it has many tiers:

  • exams/aws/foundational/ - CLF-C02 (Cloud Practitioner), AIF-C01 (AI Practitioner)
  • exams/aws/associate/ - SAA-C03, DVA-C02, SOA-C03, MLA-C01, DEA-C01, SOA-C02 (retired but retained)
  • exams/aws/professional/ - SAP-C02, DOP-C02
  • exams/aws/specialty/ - SCS-C02, ANS-C01, PAS-C01, QPC-C01, MLS-C01 (retired), DAS-C01 (retired), DBS-C01 (retired)
  • exams/aws/shared/services/ - shared service references (compute, storage, network, etc.)

Other providers don't use tier subdirs - the cert dir sits directly under the provider dir.

Files in a cert dir

Standard cert dir contents:

exams/<provider>/<cert>/
β”œβ”€β”€ README.md           # 1-page overview, quick-links, exam summary
β”œβ”€β”€ fact-sheet.md       # Dense reference: exam logistics, domains, services, doc links
β”œβ”€β”€ practice-plan.md    # Week-by-week study schedule with checkboxes
β”œβ”€β”€ notes/              # Numbered topic files: 01-foo.md, 02-bar.md, ...
β”‚   β”œβ”€β”€ 01-topic-one.md
β”‚   β”œβ”€β”€ 02-topic-two.md
β”‚   └── ...
β”œβ”€β”€ scenarios.md        # (Optional) Exam-style scenarios with explanations
β”œβ”€β”€ strategy.md         # (Optional, recommended for Pro/Specialty) Exam-day approach
β”œβ”€β”€ cram-1p.md          # (Optional) One-page cram sheet
└── cheat-sheets/       # (Optional) Decision trees, service comparisons

Required (validator fails on missing): README.md

Recommended for all certs (validator warns on missing): fact-sheet.md, practice-plan.md

Recommended for senior-tier certs only (validator warns on missing): scenarios.md, strategy.md

Optional, used selectively (validator silent): notes/, cram-1p.md, cheat-sheets/, labs/. Generated (do not hand-edit): flashcards.csv (from notes, by build-flashcards.py).

Tier classification

validate-cert-structure.sh classifies each cert as senior or junior and adjusts its checks accordingly.

Senior tier (gets scenarios.md + strategy.md as recommended): - Path contains /professional/, /specialty/, or /expert/ (AWS, etc.) - Curated cert basenames: GCP professional certs (cloud-architect, data-engineer, machine-learning-engineer, cloud-network/security/devops/database engineer, workspace-administrator), Azure expert/specialty (az-305, az-400, az-500, az-700, az-800, sc-100, sc-200), Kubernetes pro/specialty (cks, pca, ica), security senior certs (cissp, ccsp, cism, cisa, oscp), Cisco ccnp/ccie, HashiCorp/Databricks/Snowflake "professional"/"advanced" basenames, FinOps Certified Professional, VMware VCP, Anthropic claude-certified-architect-professional, CompTIA cysa-plus / pentest-plus / casp-plus.

Junior tier (everything else - foundational and associate-grade certs).

Scaffold tiers

The repo has two informal tiers of cert guide depth:

  • Light scaffold: README + fact-sheet + practice-plan + ~5 notes files. Used for Foundational and most Associate certs.
  • Full scaffold: everything in light, plus scenarios.md + strategy.md, cram-1p.md (optional), cheat-sheets/, more detailed scenarios. Used for senior-tier certs (see classification above) and high-traffic Associates (AWS SAA-C03, Azure AZ-104, K8s CKA).

When scaffolding a new cert, the validator's tier classification is the default; override only with intent.


resources/ - cross-cert resources

Subdirectories

resources/
β”œβ”€β”€ architecture-patterns/      # Multi-cloud architecture write-ups (17 files)
β”œβ”€β”€ compliance-guides/          # SOC 2, HIPAA, PCI DSS, GDPR, FedRAMP (5 files)
β”œβ”€β”€ cost-optimization/          # Per-cloud cost optimization playbooks (4 files)
β”œβ”€β”€ hands-on-projects/          # 15 guided builds + generated labs-by-cert.md index
β”œβ”€β”€ interview-prep/             # Role-based interview prep (6 files)
β”œβ”€β”€ migration-guides/           # On-prem and cloud-to-cloud migration (5 files)
β”œβ”€β”€ networking-deep-dives/      # Hybrid, multi-cloud, DNS, load balancing (4 files)
β”œβ”€β”€ practice-questions/         # Per-cert question banks (34 files + template)
β”œβ”€β”€ troubleshooting/            # Per-platform troubleshooting (4 files)
└── well-architected/           # AWS / Azure / GCP frameworks (3 files)

Top-level resource files

resources/
β”œβ”€β”€ budget-study-plan.md
β”œβ”€β”€ certification-roadmap-*.md          # 11 career-focused roadmaps
β”œβ”€β”€ cli-cheat-sheet-*.md                # 9 CLI quick references
β”œβ”€β”€ community-resources.md
β”œβ”€β”€ exam-day-checklist.md
β”œβ”€β”€ free-tier-guide.md
β”œβ”€β”€ practice-resources.md
β”œβ”€β”€ recommended-courses.md
β”œβ”€β”€ service-comparison-*.md             # 12 cross-cloud comparisons
└── study-strategies.md

.templates/ - hub pages

Three centralized cloud-specific resource hubs referenced from many cert dirs:

  • .templates/resources-aws.md
  • .templates/resources-azure.md
  • .templates/resources-gcp.md

Each consolidates official docs, lab platforms, practice exams, video courses, communities, and cost-optimization tips for that cloud. Cert READMEs link to these instead of duplicating content.

The .templates/ dir is a hidden directory (leading dot) by convention - it's not user-facing study material but contains reusable building blocks.

On the published site these three pages appear under Reference as "Provider Resource Lists", staged as provider-resources/. MkDocs skips dot-directories, and a root directory literally named templates is reserved by MkDocs and silently dropped from the build, so the site build renames the directory and rewrites the ~144 inbound links. See The published site.


The published site

The repo is published as a MkDocs Material site at patrickwiloak.github.io/cloud-data-ai-security-zero-to-hero.

The guiding constraint: the markdown tree is the source of truth and does not bend to the site generator. Reading the repo on GitHub stays a first-class experience, so the site is adapted to the tree at build time rather than the tree being restructured for MkDocs. There is no second copy of any page.

How a build works

.github/scripts/build-site.py does five things, in order:

  1. Stage. Copies the content tree into .site-src/, mirroring the repo layout so relative links and edit_uri keep working. .templates/ is renamed to provider-resources/ on the way in.
  2. Render the landing page. .github/site/home.md is written over the staged root README.md, which MkDocs serves as the site index. See The home page is not the README.
  3. Fill gaps. Generates a landing page for any directory that holds markdown but no README.md. The repo uses directory-style links (](../notes/)) about 1,200 times; GitHub renders those as a directory listing, and the site needs a real page at that URL.
  4. Rewrite links. Fence-aware pass that points directory links at the directory's README.md, redirects the renamed .templates/ paths, and sends links aimed at repo tooling (.github/...) to GitHub rather than dropping them.
  5. Generate the nav. Built from the staged tree, with section labels from docs/certs.json and page labels from each page's H1. Cert levels sort by exam progression (foundational, associate, professional, specialty, expert) and the files inside a cert dir sort in study order.

The result is appended to mkdocs.yml as mkdocs.generated.yml and built from there. mkdocs.yml holds the hand-maintained configuration and deliberately has no nav key.

What is generated, and what is not

Path Tracked? Notes
mkdocs.yml Yes Hand-maintained. Theme, extensions, validation. No nav.
.github/scripts/build-site.py Yes The generator. Edit this, not the output.
.github/site/extra.css Yes Site-only styling. Kept out of assets/, which is the diagram store.
.github/site/home.md Yes The site's landing page. Rendered over the staged README.md; never published as a page of its own.
.github/site-overrides/ Yes Material template overrides. Separate from .github/site/, whose assets are copied into the published site at assets/site/.
requirements-docs.txt Yes Fully pinned, including transitive packages that affect rendering.
.site-src/ No Staged markdown tree.
mkdocs.generated.yml No mkdocs.yml + generated nav.
site/ No Rendered HTML, ~240 MB across ~2,000 pages.

The home page is not the README

README.md and the site's home page have different jobs, and for the first day of the site's life they were the same file. A repo front page opens with a banner image, five social badges, a count-badge row, a repository-structure tree, "star this repo", and contribution instructions. Read as a website landing page, that is a wall of decoration in front of the thing a visitor came for.

So build-site.py renders .github/site/home.md over the staged copy of README.md. MkDocs treats a directory's README.md as its index, so the swap changes the site's front door without touching the repo's README, adding a second page, or breaking a link - nothing in the tree links to the root README.

Two rules keep the two pages from disagreeing:

  • No hard-coded numbers in home.md. Every figure is a {{token}} filled from docs/certs.json and from check-readme-counts.py's gather() - the same counting code CI runs against the README. A count on the landing page cannot drift from the tree, because nothing types it.
  • Release notes are extracted, not copied. The "What's new" section is lifted from the README at build time, truncated to the three most recent entries. A third hand-maintained copy of the changelog would be the one nobody updates.

The consequence to remember: editing README.md does not change the site's home page, beyond those extracted release notes. Edit .github/site/home.md.

Page layout: one sidebar, on the left

Material renders navigation on the left and the page's table of contents on the right. Two settings change that, and both have a trap:

  • navigation.tabs is off. With tabs, the left sidebar shows only the active tab's subtree. Home is a root-level page with no children, so its left column collapsed to a single link while its long table of contents filled the right, and a cert page did the reverse. The sidebar changed shape depending on where you stood. Without tabs, every page gets the same full site tree with the current branch expanded.
  • toc.integrate is on, so the table of contents folds into that same left sidebar rather than taking a second column. There is no right-hand column on any page.

toc.integrate alone is not safe here. Material emits the integrated ToC from the nav_item == page branch of partials/nav-item.html, which only fires for leaf pages. A section-index page - the effect of navigation.indexes - is represented in the nav by its section, not by a page item, so it matched no branch and rendered no ToC at all. That is every cert landing page plus every generated directory index.

.github/site-overrides/partials/nav-item.html is a copy of the upstream partial with a toc.integrate block added to the section-index branch. The addition is marked LOCAL ADDITION and is the only change; everything else is upstream.

This couples the repo to Material's template internals. requirements-docs.txt already pins mkdocs-material, and that pin now matters twice over: after any bump, re-copy the upstream partial, re-apply the marked block, and rebuild. A --strict build will not catch a drifted template, because a missing ToC is not an error. Check a cert landing page by eye.

Conventions the site depends on

  • A directory that holds markdown should have a README.md. One is generated if missing, but a hand-written index reads better.
  • Heading anchors match GitHub. The toc extension is configured with pymdownx.slugs.slugify(case="lower"), which reproduces GitHub's algorithm exactly, including the double hyphen in #security--identity and the leading hyphen an emoji heading produces. A missing-anchor error from the build means the link is broken on GitHub too.
  • A new top-level directory needs a TABS entry in build-site.py. The build fails rather than silently dropping its pages from the navigation.
  • Code fences must be balanced. An unclosed fence swallows everything up to the next one, on GitHub and on the site alike. A --strict build surfaces this as missing anchors on the affected page.

Versions are pinned for a reason

Two pins in requirements-docs.txt are load-bearing. pymdown-extensions must be 11+ against Pygments 2.20, or any indented code block aborts the build. And mkdocs-material is held at 9.x because MkDocs 2.0 removes the plugin system and rewrites theming with no migration path.


Use the standard format:

**[πŸ“– Link Text](URL)** - Optional short description

Use relative paths:

  • Within a cert dir: [fact-sheet](./fact-sheet.md)
  • To another cert: [SAA-C03](../../associate/solutions-architect-saa-c03/)
  • To resources: [Cloud Engineer Roadmap](../../../resources/certification-roadmap-cloud-engineer.md)

Link audits run with a code-block-aware scanner. See CONTRIBUTING.md for the doc-link policy.

Style conventions

  • No em dashes (-) anywhere - house style
  • Avoid emojis in body text - the repo uses a small set of section-marker emojis (☁️, πŸ”’, πŸ“–, ⚠️, ℹ️, 🎯, πŸ“š) but body content stays plain
  • Plain English, short sentences
  • Cite, don't paraphrase vendor docs - link them
  • No verbatim vendor exam questions - legal and ethical violation

Visual content standards

Where diagrams go

  • Canonical: Mermaid in fenced ```mermaid code blocks, written inline in the page that uses it. GitHub renders it natively. It stays editable in the markdown, diffs as text in review, needs no tooling to update, and never rots into a broken image link.
  • Exception: PNG files under assets/diagrams/<topic>/<slug>.png, for diagrams too dense to read inline - large multi-region topologies, detailed multi-service reference architectures. Topic subdirs are created lazily: cloud/, ai/, networking/, architecture/, security/.

Reach for Mermaid first. Only fall back to PNG when the diagram genuinely does not read as inline text.

This reflects what the repo actually does: 89 pages use Mermaid today and no PNG has ever been added. The convention previously named PNG as canonical, which meant the documented standard had zero instances while the real one was undocumented.

Authoring

For Mermaid, prefer flowchart TB / flowchart LR over the older graph syntax. Use subgraph blocks for grouped components (regions, AZs, tiers). Keep node labels short; put detail in the surrounding prose, not inside the boxes.

Mermaid renders in GitHub's light and dark themes, so do not hard-code colours that only work against one background. Default styling is preferred.

PNG diagrams, when justified, are created with the draw.io MCP server. Export at 2x resolution for retina screens and keep files under 200 KB.

Embedding

Mermaid: a fenced code block tagged mermaid. Don't wrap it in HTML.

```mermaid
flowchart LR
    Client --> LB[Load balancer]
    LB --> App1[App server]
    LB --> App2[App server]
    App1 & App2 --> DB[(Database)]
```

Because a Mermaid diagram carries no alt text, give it a caption or a sentence of surrounding prose that states what it shows. Screen readers and anyone whose renderer does not support Mermaid rely on that text.

PNG: always include descriptive alt text, useful both when the image fails to render and for screen-reader users.

![3-tier architecture with load balancer, two app servers, and a database](../../assets/diagrams/architecture/web-app-3-tier.png)

Where to add diagrams

Highest-ROI pages for diagrams: - learn/cloud-from-scratch.md, learn/ai-from-scratch.md (foundational paths) - learn/concepts/ AI pages: transformer-architecture, RAG, agents - resources/architecture-patterns/ (every pattern benefits from a diagram) - resources/networking-deep-dives/ (network topologies)

Lower-ROI: cert fact-sheets, practice plans, study strategies. Don't force diagrams onto pages that read fine without them.


Frontmatter convention

New pages and (opportunistically) refreshed pages should use YAML frontmatter for living-doc metadata:

---
last-updated: 2026-05-03
applies-to: AWS console as of 2026-Q2          # optional
difficulty: beginner                           # optional: beginner | intermediate | advanced
reading-time: 10 min                           # optional
---
  • last-updated is the only required field. Use ISO date format (YYYY-MM-DD).
  • applies-to is for content tied to a specific console version, exam version, or product release that may drift.
  • difficulty and reading-time help readers calibrate.

Backfill is opportunistic, not blocking. Don't open a PR that adds frontmatter to 1300 existing files at once. When you touch a file, add it.

The link audit script below is YAML-frontmatter safe (frontmatter contains no markdown link syntax).


How retired certs are handled

When a vendor retires a cert:

  1. The cert dir stays in the repo (don't delete - credential holders need the material)
  2. Add a RETIRED [DATE] banner block to the top of README.md and fact-sheet.md
  3. Link to the modern replacement
  4. Update README.md and STUDY-HUB.md to mark the cert as retired in the provider listing
  5. Update any roadmaps that recommended the retired cert
  6. Add an entry to CHANGELOG.md

The canonical retired-banner pattern is in exams/aws/specialty/data-analytics-das-c01/README.md.


How aspirational / non-cert study tracks are handled

Some dirs in exams/ cover topics that aren't tied to a specific certification (e.g., the Anthropic Prompt Engineering Specialist track, AWS Quantum before formal exam announcement, cross-cert GenAI study tracks). These get a clear disclaimer:

> ℹ️ **Study track, not an official certification.** [Vendor] does not currently run a discrete certification for this material. Use this as a self-directed proficiency track.

The README and STUDY-HUB call these out as "study tracks" separately from certified exams in the provider tables.


Counts and consistency

The README, STUDY-HUB, and CLAUDE.md all claim specific counts:

  • 148 certifications
  • 3 study tracks
  • 27 providers

When you add or remove a cert, update all three docs to keep counts consistent. The provider table in STUDY-HUB is the canonical source - everything else should match it.

For verification:

# Count cert dirs (excluding study tracks):
find exams -mindepth 2 -maxdepth 4 -type d ! -name notes ! -name shared ! -name foundational ! -name associate ! -name professional ! -name specialty ! -name genai ! -name services ! -name cheat-sheets ! -name compute ! -name database ! -name networking ! -name storage ! -name security-identity | wc -l

# Or per-provider:
for d in exams/*/; do
    name=$(basename "$d")
    count=$(find "$d" -mindepth 1 -maxdepth 1 -type d ! -name notes | wc -l)
    echo "$name: $count"
done

Run periodically to catch doc drift. The scanner is code-block aware (skips fenced blocks and inline backticks).

check_links() {
    local file="$1"
    local dir=$(dirname "$file")
    awk '/^```/ { in_block = !in_block; next } !in_block { gsub(/`[^`]*`/, ""); print }' "$file" \
        | grep -oE '\]\([^)]+\)' \
        | sed 's/^](//; s/)$//' \
        | while read link; do
            case "$link" in http://*|https://*|mailto:*|"#"*) continue ;; esac
            path="${link%%#*}"
            [ -z "$path" ] && continue
            if [[ "$path" = /* ]]; then target="${path#/}"; else target="$dir/$path"; fi
            target=$(realpath -m --relative-to=. "$target" 2>/dev/null)
            [ -e "$target" ] || echo "  $file -> $link"
        done
}
for f in $(find . -name "*.md" -not -path "./.git/*"); do check_links "$f"; done

The repo currently has 0 broken internal links (as of 2026-04-27).


When to update top-level docs

Change Update
Add a new cert README provider table, STUDY-HUB provider table, CHANGELOG, relevant roadmap
Retire a cert Banners on cert dir, README, STUDY-HUB, roadmaps, CHANGELOG
Add a new provider All of the above plus README structure section
Rename a cert dir Sweep grep -rn "old-slug" and update all references; CHANGELOG
Change repo conventions Update CONTRIBUTING.md and this file

Where things live

Looking for... Find it in
Cert overview, exam logistics exams/<provider>/<cert>/README.md
Deep service / domain reference exams/<provider>/<cert>/fact-sheet.md
Study schedule exams/<provider>/<cert>/practice-plan.md
Topic deep-dives exams/<provider>/<cert>/notes/NN-topic.md
Practice questions resources/practice-questions/<provider>-<cert>.md
Cross-cloud service comparisons resources/service-comparison-*.md
Career path guidance resources/certification-roadmap-*.md
Architecture patterns resources/architecture-patterns/*.md
CLI quick reference resources/cli-cheat-sheet-*.md

Anti-patterns to avoid

  • Don't create new content categories silently. If you want a new top-level resource type, propose it in an issue first.
  • Don't reference files that don't exist. Run the link audit before submitting a PR.
  • Don't duplicate cross-cloud content. Use service-comparison-*.md for comparisons, not per-cert duplicates.
  • Don't leave retired certs unmarked. A retired cert without a banner is misleading.
  • Don't bloat README/STUDY-HUB. Both should stay scannable; depth lives in cert dirs and resource files.
  • Don't over-template. Light-scaffold certs (READMe + fact-sheet + practice-plan + notes) are valuable; not every cert needs scenarios + strategy + cheat-sheets.

Contact

See CONTRIBUTING.md for contribution workflow, PR checklist, and contact info.