docs: add READMEs, CLAUDE.md, and markdown linting - #7
Merged
Conversation
- Add CLAUDE.md with project overview, deployment ordering, key commands, testing conventions, and architecture decisions - Add module READMEs: eks, eks-node-group, ssm-bastion, github_oidc (following MODULE-README-TEMPLATE with terraform-docs markers) - Add live unit READMEs: networking, eks, cilium, node-groups, ssm-bastion (following TERRAGRUNT-README-TEMPLATE) - Update cilium module README for multi-cloud (was Azure-only) - Update Azure cilium live READMEs for cloud_provider variable - Add markdownlint config (.markdownlint.yml, .markdownlintignore) - Add markdown-lint and terraform-docs CI jobs to ci.yml - Add markdownlint and terraform-docs checks to pre-commit hook Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The terraform-docs/gh-actions action fails on modules without BEGIN_TF_DOCS markers. Replace with a custom script that only checks modules that have opted in. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pre-commit hook still runs terraform-docs locally. CI job can be re-enabled once all module READMEs have been migrated to use markers. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
15 tasks
gangster
added a commit
that referenced
this pull request
Jun 1, 2026
…ocs) (#159) * docs(arch): audit aws-organizations.md for accuracy - 4 accounts not 2 (add Test in Platform OU, Prod in Workloads/Prod); OU tree + module-processing trace updated - AWS provider 6.47.0 (was 5.91.0) - enforce-encryption: add missing DenyUnencryptedEbsOnLaunch + DenyUnencryptedS3Uploads statements - protect-data-and-network: add DenyTeamTagTampering (ABAC tag integrity, #62) - exempt roles: document all three (OrganizationAccountAccessRole, PlatformDeployer, github-actions-terratest), not just one - fix 'Three statements' count in CANNOT-bypass table; reconcile HIPAA ~90 services Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(arch): rewrite config-hierarchy.md AWS-first and accurate The doc predated the AWS-first pivot — it described a 7-layer hierarchy with Azure/GCP as deployed clouds. Reframed to current reality: - 6-layer hierarchy (root/common/env/region+network/workload/unit); _versions.hcl and _base.hcl documented as supporting files, not layers (matches CLAUDE.md + ADR-001) - AWS-only: no live/azure or live/gcp trees exist; removed fabricated Azure aks_core / dev-eastus examples, _envcommon, and module-count tables; Azure/GCP now a concise 'planned, same pattern' section - cloud detection defaults to 'aws' (not 'azure'); only provider_aws generated - AWS provider 6.47.0 (was 5.91.0) - env layer is env.hcl; envs are mgmt/platform/preprod/prod/test (not ops/dev) - environment_account_map sourced from secrets.hcl; state bucket/role from secrets - 2 safety assertions (env-path + account), not 3 (dropped nonexistent 'Azure workload-path') - _versions.hcl has ~37 module sources + ~10 helm pins (not '4 modules / empty helm map') Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(arch): cosign-image-signing §10b — SLSA L3 cutover done on preprod Provenance is now signed solely by the isolated trusted-ci reusable workflow and verify-attestations is in Enforce on preprod (Build L3 achieved); was described as 'today hand-authored / dual-provenance first / swaps later'. Platform replication (P4) pending. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(arch): preprod-tenant-model — fix ADR-027 link, add Pod Identity egress policy - fix broken link (027-hybrid-tenant-isolation -> -model); add ADR-041 to related - add the 5th tenant policy allow-pod-identity-egress (CiliumNetworkPolicy, host egress to the Pod Identity agent 169.254.170.23:80, ADR-041) to the resource table + network topology; correct count to 'two CiliumNetworkPolicies' Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(arch): platform-capability-coverage — observability now live, security depth shipped - Observability #7: ❌ Missing -> 🟡 Partial (metrics+Mimir+dashboards+SNS alerting live on hub ADR-043/044, Falco runtime detection ADR-045); remaining = logs/traces/cost + spoke fan-in. Reordered into the 🟡 group. - Reframe strategic gaps: DX/self-service is now the dominant gap; security-depth items (SBOM, SLSA L3, Falco, Semgrep SAST) have largely shipped. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(arch): kyverno-policy-catalog — add attestation verification, fix per-team count rationale - add the deployed verify-attestations-team-<team> policy (CycloneDX SBOM + SLSA provenance, trusted-ci for L3-adopted teams; Enforce on preprod 2026-05-30, ADR-042) — was missing - fix the '+2 per-team policies' explanation: four policy families are per-tenant (restrict-images, restrict-route-hostnames, verify-images, verify-attestations); counts are an indicative snapshot, read live via kubectl get cpol Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(arch): observability-current-state — P2 Step 3 / PR #147 now merged (was 'finalizing') Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(arch): supply-chain-overview — fix app-beta -> app-bravo (team naming) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(compliance): scp-control-mapping — add missing SCP statements + all 3 exempt roles - enforce-encryption: add DenyUnencryptedEbsOnLaunch + DenyUnencryptedS3Uploads to the control-mapping table and description (audit completeness) - protect-data-and-network: add DenyTeamTagTampering (ABAC tag integrity) - exempt-role governance: list all three (OrganizationAccountAccessRole, PlatformDeployer, github-actions-terratest) + note the no-exemption statements — important for auditors - bump Last reviewed to 2026-06-01 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(runbook): modify-scps — fix exempt_roles examples to keep all 3 live roles Both exempt_roles examples showed only OrganizationAccountAccessRole + a break-glass role; copying them would drop PlatformDeployer (breaks IaC apply) and github-actions-terratest (breaks CI). Show the real three + append pattern with DO-NOT-REMOVE warnings. Also clarify the DenyUnencryptedS3Uploads 'add a statement' example already ships; bump review date. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(runbook): incident-scp-blocking — exempt_roles append pattern + new SCP error rows - Step 3a exempt_roles: keep all 3 live roles (don't drop PlatformDeployer/terratest) - SCP-to-error table: add DenyUnencryptedEbsOnLaunch, DenyUnencryptedS3Uploads, DenyTeamTagTampering - bump review date Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs: review troubleshooting/aws-organizations + align HIPAA service count to ~117 - troubleshooting/aws-organizations.md: reviewed (OU hierarchy + procedures accurate); HIPAA count 120+ -> ~117; bump review date; make lint-clean (MD040 add 'text' to bare error-output fences, MD036 convert bold 'Error: ...' sub-headings to #### headings — pre-existing, now in CI scope since the file is touched) - correct HIPAA count to ~117 in aws-organizations.md (was my earlier ~90 guess) and scp-control-mapping.md (was 120+) — now consistent with scps.tf Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(terraform): variable_validation_standards — AWS-first reframe Principles are cloud-agnostic and correct; the concrete examples were all Azure (in an AWS-only repo). Add an AWS-context note, replace the Azure-region example with the AWS allowed-regions pattern (us-east-1/us-west-2, matching deny-regions SCP), and azurerm_example -> aws_acm_certificate. Remaining Azure-named examples kept as pattern illustrations (noted as transferable to AWS). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(runbook): secrets-management — clarify tenant secrets vs Pod Identity ClusterSecretStore name (aws-secrets-manager) verified correct. Sharpen the App-Team-Secret note: per-namespace ESO SecretStores are still the target model (ADR-024 pending), but tenant AWS resource access is already live via EKS Pod Identity (ADR-041), not ESO; ClusterSecretStore now on platform+preprod. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(runbook): tenant-onboarding — add hostnames (required), Pod Identity, cosign - teams.hcl example was missing hostnames: a team onboarded without it has ALL HTTPRoutes denied by Kyverno (ADR-029). Add hostnames to the example + a prominent warning; add optional aws/Pod-Identity block - note to apply pod-identity + s3-shared units when an aws block is declared (ADR-041) - point to app-supply-chain-onboarding for cosign signing (images must be signed to pass admission) - verification: add allow-pod-identity-egress to expected CiliumNetworkPolicies Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(runbook): kyverno-break-glass — note separate verify_attestations_failure_action knob Attestation verification (SBOM + SLSA provenance, incl. trusted-ci L3) has its own failure-action, independent of validation and image-signature verification — can be flipped to Audit for break-glass without weakening the signature gate (ADR-042). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(runbook): upgrade-procedures — add observability/Mimir/Falco/vCluster to version table All existing pins verified correct. Add the components that shipped this week: kube-prometheus-stack 86.1.0 + Mimir 6.0.6 (platform-only), Falco 9.0.0 (preprod-only), vCluster 0.34.1 (deferred). Note their single-cluster placement skips the preprod-first sequencing. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(runbook): tailscale-vpn — note preprod subnet router (10.101) Doc covered only the platform cluster; preprod also runs a tailscale unit advertising 10.101.0.0/16 (split DNS -> 10.101.0.2), which is what provides operator kubectl access to the now-private preprod API. Namespace tailscale-system verified correct; bump review date. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(user-guide): AWS-current — platctl, 4 accounts, IAM roles, ops->platform - bootstrap/teardown use platctl (ADR-038); scripts/bootstrap-platform.sh is gone. ~30 units, not 16 - greenfield expected: 4 member accounts (platform/test/preprod/prod), not 2 - IAM roles table: PlatformAdmin (Platform+PreProd), PlatformDeployer (+Test), DeveloperAccess-<team> on PreProd per-team (was wrongly 'Platform') — matches ADR-007/039/040 - fix stale ops/ path in dependency example -> platform/ Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(onboarding): AWS-first/current — structure, 6-layer, platctl, 4 accounts - repo structure tree: root.hcl (not terragrunt.hcl); AWS-only modules/live (removed nonexistent naming/azure/gcp modules + azure/gcp live + charts/ + planning/); add cmd/platctl; env.hcl - config hierarchy: seven-layer -> six-layer, drop _envcommon, env.hcl, note _versions/_base as supporting - greenfield: 4 accounts (platform/test/preprod/prod); platctl bootstrap/teardown (ADR-038, ~30 units) replaces the removed scripts/bootstrap-platform.sh Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(interview-prep): reframe multi-cloud overclaims as AWS-first azure/gcp modules are planned (not present); the tenant model is designed for AKS/GKE but only AWS/EKS is deployed. Rest of the doc (IaC structure, state, SCPs) is accurate. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(index): README — AWS-first framing, six-layer, add key architecture docs - multi-cloud (AWS,Azure,GCP) -> multi-cloud-by-design, AWS-first today - Config Hierarchy: seven-layer -> six-layer; link the config-hierarchy.md doc (not _base.hcl) - add cosign, kyverno-policy-catalog, aws-organizations, platform-capability-coverage to How It Works - repo layout: aws/+shared modules (azure/gcp planned), live/aws only, add cmd/platctl Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(runbook): deploy-app-preprod — per-team ECR role, drop :latest, note signing CI examples used the removed shared github-actions-ecr-push role (now per-team, ADR-036/#60), pushed :latest (denied by Kyverno disallow-latest-tag), and omitted cosign signing (required by verify-images Enforce). Fix both build-push.yml and preview.yml: per-team role, immutable SHA tag only, and a pointer to app-supply-chain-onboarding for signing/SBOM/provenance. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(plans): update status — observability P1/P2 live, SLSA L3 done on preprod - 102-observability-stack: 'implementation not started' -> P1+P2 (Mimir) DONE and live (ADR-043/044, PR #147); points to observability-current-state as-built - 131-slsa-build-l3: 'P2-P4 not started' -> P1-P3 DONE on preprod (Build L3 achieved), P4 remaining - slsa-l3-provenance-cutover-HANDOFF: marked COMPLETE/superseded by ADR-042 (retained for history) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
gangster
added a commit
that referenced
this pull request
Jun 4, 2026
#209) After a long node-group-at-zero downtime, the Tailscale subnet-router pod's stored node key goes invalid; it restarts in NeedsLogin and asks the operator to reissue an auth key, but the operator reports ConnectorReady=True and never mints one into the secret's empty reissue_authkey field -> 10-min timeout -> CrashLoop -> the cluster's whole route is unadvertised and the cluster is unreachable over Tailscale (kubectl resolves but times out -- distinct from the split-DNS conflict #1). Fix: delete the wedged state secret + pod so the operator re-provisions a fresh auth key and the pod re-registers. Observed on preprod during the 2026-06-04 scale-up incident (#206). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
gangster
added a commit
that referenced
this pull request
Jul 12, 2026
…(real alpha/bravo names) (#1387) * docs(observability): accuracy + teachability sweep of the deep dives; adopt real alpha/bravo names Pressure-tested all five observability deep dives against primary-source code (not other docs — the tenant-proxy incident showed the as-built doc and skill were themselves stale). Fixes the accuracy failures, which clustered in the low-attention spots (headers, gotchas, code-block field names, hard counts, "live output" blocks), and applies the bounded teachability edits. CRITICAL accuracy: - stack-and-storage: header, a datasource bullet, and Gotcha #7 still described the RETIRED fail-closed tenant-proxies as live (Gotcha #7 asserted a false security guarantee). Rewritten to the soft read model (folder perms + #1157 dashboards; proxy retired #1269, read_proxy_url=""; network default-deny is the real data-plane boundary). Also corrected the federated datasource header platform|preprod -> platform|preprod|alpha|bravo (verified vs the module). - correlation + reference + orientation + correlation-walk.svg: `tracesToProfilesV2` is the broken field Grafana silently ignores (#1269) — the real field is `tracesToProfiles` (no V2; logs has a V2, profiles does not). Fixed everywhere it appeared, incl. the shipped diagram label. Loki derived-field url escape fixed to the required `$$${__value.raw}` (three $). MAJOR accuracy: - slos: alert count "42 across 12 groups" -> the real "61 across 20"; freeze-gate reframed (one-shot pre-flight: freezes if the service is ALREADY burning >=2x, never blocks a first deploy). - collection: hub/spoke table cell for the OTel operator/CRD on the spoke was wrong (shown absent) — it's live with 5 CRs; exclusion mechanism corrected to the `exclude_instrument` annotation predicate (namespace stays in the glob). Naming: the deep dives now use the REAL running apps (alpha/bravo) instead of generic acme/globex — which also makes the "live kubectl output" blocks genuinely verifiable (real teams are alpha/bravo/platform). Orientation + the 9 diagrams keep acme/globex for now (that retrofit is a separate follow-up). Teachability (bounded): two-SLO-systems compare table; a stitched end-to-end triage walk; front-loaded takeaways; de-duplicated the repeated hub-first point; glossed cortex-tenant / exemplar / Downward API / serviceMonitorSelectorNil...; worked example of one opted-in pod; burn-rate multiplier->error-ratio; PagerDuty status de-dated in the reference. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(observability): retrofit orientation + diagrams to real alpha/bravo names Extends the real-name adoption from the deep dives to the orientation prose and the three shipped diagrams that carried generic team names (correlation-walk, hub-and-spoke, isolation-model): acme->alpha, globex->bravo, acme-shop->alpha-shop, acme-checkout->alpha-checkout, globex-widgets->bravo-dispatch. Team + product names only; the friendly service names (shop-web/checkout) stay so the orientation and its diagrams remain internally consistent. SVG label swaps are <=+1 char, verified in dark mode (no overflow/gluing). The whole observability section now uses the real running apps. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(observability): fix reference alert count ~40 -> ~60 (missed in the sweep) The reference's alerting line still said ~40 curated rules; the real count is 61 across 20 groups (curated.yaml) — matching the deep-dive fix. A textbook instance of the very trap being captured: a stale count survived in a reference. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(observability): place the 5 Tier-1 deep-dive diagrams The deep dives had zero diagrams (all 9 visuals were in the orientation) — the biggest gap flagged in the pressure-test. Places one signature diagram per deep dive at its section anchor, each going mechanism-deep where the orientation's overview diagrams don't: - pipeline-swimlanes → collection §End-to-end flow (kernel→collector→store, all signals) - correlation-web → correlation §end of Part 1 (the replace(uid,…) convention across tenants) - two-slo-pipelines → slos §Two generators (Sloth vs auto-derived, one burn-rate shape) - isolation-status → stack-storage §Honest status (hard write / soft read / retired proxy) - eval-feedback-loop → agent-obs §The three slices (the human-verdict calibration loop) Baked light+dark via theme-svg.mjs; all verified in dark mode (no word-glue on the multi-line SVGs, house colour grammar, real alpha/bravo names). isolation-status doubles as a visual lock on the corrected read-isolation story. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(observability): place the 10 Tier-2/3 deep-dive diagrams Completes the deep-dive diagram program — two per doc, going a level deeper than the Tier-1 signature diagrams: collection: beyla-vs-sdk-fragmentation (L0/L1 traceparent split + the fix), three-alloys (one binary, three topologies) correlation: loop-vs-oneway (SDK closes the loop, Beyla-only doesn't), fragile-seam (service.name agreement, not declaration) slos: alert-routing-tree (severity plumbing before ownership), opencost-vs-cur (speedometer vs odometer, the sum() trap) stack: storage-shape (disposable hot buffer, durable S3 tail), network-perimeter (tenancy is a network boundary, not a header) agent: triage-span-tree (replaces the bare mermaid with an annotated span tree), content-capture-tiers (metadata always / content gated / regulated never) All baked light+dark via theme-svg.mjs; every one verified in dark-mode Chrome (no word-glue on the multi-line SVGs, house colour grammar, real alpha/bravo names). The agent-obs mermaid block is removed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(observability): re-render eval-feedback-loop as a closed ring The first render was a numbered vertical flow with a 'back to 1' note — it read as a checklist, not a loop. Re-rendered as a true closed ring: 5 nodes clockwise (agent disposition → Slack proposal → human verdict → counter → accept-rate) with curved arrows completing the cycle, 'is the agent calibrated?' in the center, and the same-machine / confidently-wrong / cold-agent callouts outside the ring. Placement unchanged. Verified in dark mode (no arrow/label overlap). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
CLAUDE.mdwith project overview, deployment ordering, commands, testing conventions, and architecture decisionseks,eks-node-group,ssm-bastion,github_oidc(followingMODULE-README-TEMPLATEwithterraform-docsauto-generated sections)networking,eks,cilium,node-groups,ssm-bastion(followingTERRAGRUNT-README-TEMPLATE)ciliummodule README for multi-cloud support (was Azure-only)cloud_providervariable.markdownlint.ymlconfig,.markdownlintignore, CI job (lints changed files only), pre-commit hookterraform-docsfreshness check to CI and pre-commit hookTest plan
markdownlint-cli2 CLAUDE.md infra/modules/aws/*/README.md infra/modules/cilium/README.md infra/live/aws/platform/us-east-1/platform/*/README.mdreturns 0 errors<!-- BEGIN_TF_DOCS -->markers with auto-generated content🤖 Generated with Claude Code