CNPA — Cloud Native Platform Engineering Associate
Delivering Golden-Path Conformance as a Diagnostic
Goal
You define golden path rules as values, build a diagnostic tool that actually evaluates them, and go all the way through to counting the compliance rate and attaching it in front of commits.
Why it matters
If you block rules only at admission, developers learn about a problem that takes 1 minute to fix only 30 minutes later, and if you block everything up front, people get around the platform. So in practice, guardrails are placed on two tracks. Rules whose violation harms other people are blocked, and rules that are that service's own problem are only announced. For that, a rule must carry an identifier, a severity, and a way to fix it. And a diagnostic tool must always be tested in the opposite direction too. A diagnostic tool that catches nothing makes the compliance rate look like 100%, which is worse than having none.
Steps
- Write five rules as an array in
/root/cnpa-devex/rules.json. Each element hasid,title,severity, andfix.PR001(pin the image tag) andPR002(declare resource requests) haveseverityset toblock, andPR003(the standard labelsapp.kubernetes.io/nameandapp.kubernetes.io/part-of),PR004(readinessProbe), andPR005(replicas of 2 or more) arewarn. Writefixwith at least 8 characters. - Create
/root/cnpa-devex/check-paved-road.shand give it execute permission. It reads the manifest passed as an argument and prints the ids of the rules it breaks, one per line. At this step it is enough to evaluate onlyPR001andPR002.PR001is when the first container's image has no tag or the tag islatest, andPR002is when the first container lacksresources.requests.cpuorresources.requests.memory. - Fill in the remaining three rules.
PR003is whenmetadata.labelslacksapp.kubernetes.io/nameorapp.kubernetes.io/part-of,PR004is when the first container has noreadinessProbe, andPR005is whenspec.replicasis missing or less than 2. It must exit with code 0 if there are no violations and 1 if there is even one. - Write a Deployment
checkoutthat follows all five rules in/root/cnpa-devex/services/checkout.yaml. The file contains only one Deployment. - Write a Deployment
reportsin/root/cnpa-devex/services/reports.yaml. It must break onlyPR001andPR005. In/root/cnpa-devex/services/billing.yaml, write a Deploymentbillingthat breaks onlyPR004. - Add a
--jsonmode to the diagnostic tool.check-paved-road.sh --json <파일>(where the placeholder is the manifest file) prints one JSON object of the form{"file": "<받은 경로>", "violations": ["PR001", ...], "pass": true 또는 false}(where the file value is the path that was passed in, and pass is either true or false).passis an unquoted boolean, and if there are no violations,violationsis an empty array. - Run the diagnostic tool on every manifest in
/root/cnpa-devex/services/and create/root/cnpa-devex/adoption.json. The keys aretotal(the number of files checked),passing(the number of files with no violations),rate_pct(the compliance rate, to one decimal place), andby_rule(the number of violating files for each of the five rules; include a key even for rules with 0). - Create a git repository at
/root/cnpa-devex/repoand put aservices/directory in it. Create.git/hooks/pre-commit, give it execute permission, and have it check the stagedservices/*.yamlwith the diagnostic tool. If any file breaks ablockrule, it prints the rule id and exits with a non-zero code to block the commit, and if it breaks onlywarnrules, it prints only guidance and lets the commit through. Try one blocked commit and save its output to/root/cnpa-devex/blocked-commit.txt.
Notes
- When you read a missing value with yq, the string
nullcomes out. You can use that as the evaluation condition. - Wrap label keys that contain dots in quotes, as in
.metadata.labels."app.kubernetes.io/name". - The grader feeds its own sample manifests to your diagnostic tool and compares the verdicts. Rule ids must be printed exactly as the specified names.
- The hook in step 8 is tested not in the student's repository but in a copy of it. You do not need to leave the repository in a clean state.
Define the rules as values
Write five rules as an array in /root/cnpa-devex/rules.json. Each element has id, title, severity, and fix. PR001 (pin the image tag) and PR002 (declare resource requests) have severity set to block, and PR003 (the standard labels app.kubernetes.io/name and app.kubernetes.io/part-of), PR004 (readinessProbe), and PR005 (replicas of 2 or more) are warn. Write fix with at least 8 characters.
Each rule needs an identifier, a title, a severity, and a way to fix it. Severity is decided by 'does breaking it harm other people?'
The diagnostic tool's skeleton and two rules
Create /root/cnpa-devex/check-paved-road.sh and give it execute permission. It reads the manifest passed as an argument and prints the ids of the rules it breaks, one per line. At this step it is enough to evaluate only PR001 and PR002. PR001 is when the first container's image has no tag or the tag is latest, and PR002 is when the first container lacks resources.requests.cpu or resources.requests.memory.
Read the manifest values with yq. A missing value comes out as the string null, so you can use that as the evaluation condition. Don't forget the execute permission.
Evaluate all five rules
Fill in the remaining three rules. PR003 is when metadata.labels lacks app.kubernetes.io/name or app.kubernetes.io/part-of, PR004 is when the first container has no readinessProbe, and PR005 is when spec.replicas is missing or less than 2. It must exit with code 0 if there are no violations and 1 if there is even one.
The label is a key that contains dots, so in yq it must be wrapped in quotes. For replicas, you must catch both the case where the value is absent and the case where it is 1.
A compliant sample
Write a Deployment checkout that follows all five rules in /root/cnpa-devex/services/checkout.yaml. The file contains only one Deployment.
Create one Deployment that follows all five rules. The diagnostic tool must print nothing and exit with 0.
Deliberately rule-breaking samples
Write a Deployment reports in /root/cnpa-devex/services/reports.yaml. It must break only PR001 and PR005. In /root/cnpa-devex/services/billing.yaml, write a Deployment billing that breaks only PR004.
It must break exactly the specified rules and only those. If it breaks other rules too, grading fails even if the diagnostic tool is correct.
Machine-readable output
Add a --json mode to the diagnostic tool. check-paved-road.sh --json <파일> (where the placeholder is the manifest file) prints one JSON object of the form {"file": "<받은 경로>", "violations": ["PR001", ...], "pass": true 또는 false} (where the file value is the path that was passed in, and pass is either true or false). pass is an unquoted boolean, and if there are no violations, violations is an empty array.
Output the same verdict as one JSON object as well. pass must be an unquoted boolean, and when there are no violations, violations must be an empty array.
Calculate the compliance rate
Run the diagnostic tool on every manifest in /root/cnpa-devex/services/ and create /root/cnpa-devex/adoption.json. The keys are total (the number of files checked), passing (the number of files with no violations), rate_pct (the compliance rate, to one decimal place), and by_rule (the number of violating files for each of the five rules; include a key even for rules with 0).
Sweep the services directory, run the diagnostic tool, and count the results. Don't write the numbers by hand; put in the calculated values.
Attach it in front of commits
Create a git repository at /root/cnpa-devex/repo and put a services/ directory in it. Create .git/hooks/pre-commit, give it execute permission, and have it check the staged services/*.yaml with the diagnostic tool. If any file breaks a block rule, it prints the rule id and exits with a non-zero code to block the commit, and if it breaks only warn rules, it prints only guidance and lets the commit through. Try one blocked commit and save its output to /root/cnpa-devex/blocked-commit.txt.
A hook runs only if it has execute permission. git tells you the list of staged files, and the hook must exit with a non-zero value only for block rules.