<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Tommy Huynh</title>
    <description>The latest articles on DEV Community by Tommy Huynh (@tnptommy).</description>
    <link>https://dev.to/tnptommy</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3802592%2Ffd975981-7c66-49d5-8c47-754356bea213.jpg</url>
      <title>DEV Community: Tommy Huynh</title>
      <link>https://dev.to/tnptommy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tnptommy"/>
    <language>en</language>
    <item>
      <title>Building TNP: Why I Built an Enterprise-Realistic DevOps Lab (Part 0)</title>
      <dc:creator>Tommy Huynh</dc:creator>
      <pubDate>Mon, 27 Jul 2026 02:25:56 +0000</pubDate>
      <link>https://dev.to/tnptommy/building-tnp-why-i-built-an-enterprise-realistic-devops-lab-part-0-41ie</link>
      <guid>https://dev.to/tnptommy/building-tnp-why-i-built-an-enterprise-realistic-devops-lab-part-0-41ie</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;🧭 &lt;strong&gt;This is Part 0 of a 10-part series&lt;/strong&gt; documenting a self-built, enterprise-realistic DevOps lab — modeled after a fictional fintech company, not a pile of unrelated tools.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Most homelab tutorials teach tools in isolation. This series teaches them &lt;strong&gt;working together&lt;/strong&gt;, inside a fictional company with real constraints.&lt;/li&gt;
&lt;li&gt;Meet &lt;strong&gt;TNP Technologies&lt;/strong&gt; — a fictional fintech with 150 employees, hybrid infrastructure, and a product called &lt;strong&gt;TNP Pay&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The lab runs entirely on &lt;strong&gt;one 64GB Windows machine&lt;/strong&gt;, no cloud dependency for the core loop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;10 parts&lt;/strong&gt;, from infrastructure setup to chaos engineering — each one builds on the last.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The problem with most homelab tutorials
&lt;/h2&gt;

&lt;p&gt;Most DevOps homelab guides follow the same pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;install Docker → install Kubernetes → install Prometheus → done
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You end up with a pile of tools running side by side. Each one works. None of them talk to each other the way they would inside a real company.&lt;/p&gt;

&lt;p&gt;That's not what a DevOps engineer actually does. The job isn't &lt;em&gt;"know 15 tools."&lt;/em&gt; It's &lt;strong&gt;"make 15 tools work together to ship and operate software safely."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So instead of building a lab that teaches tools in isolation, I built one around a fictional company — with fictional constraints, fictional teams, and a fictional product that actually needed to run.&lt;/p&gt;

&lt;p&gt;This series documents that build, end to end.&lt;/p&gt;




&lt;h2&gt;
  
  
  Meet TNP Technologies
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;TNP Technologies JSC&lt;/strong&gt; is a fictional fintech company — a digital banking platform with about 150 employees and a &lt;strong&gt;hybrid infrastructure&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;🇻🇳 On-premises (Vietnam)&lt;/td&gt;
&lt;td&gt;Data residency &amp;amp; compliance for financial data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;☁️ AWS&lt;/td&gt;
&lt;td&gt;Everything that isn't sensitive&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I picked fintech on purpose. It's not a neutral choice — it forces real constraints onto the lab that a generic &lt;em&gt;"todo app in Kubernetes"&lt;/em&gt; tutorial never has to deal with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📝 Every infrastructure change needs an &lt;strong&gt;audit trail&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;🔐 Secrets can't sit around as static values forever&lt;/li&gt;
&lt;li&gt;🧱 Environments (dev/staging/prod) need to be &lt;strong&gt;genuinely isolated&lt;/strong&gt;, not just namespaced by convention&lt;/li&gt;
&lt;li&gt;🛡️ Code doesn't reach production without passing &lt;strong&gt;security scans&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;⏱️ Uptime matters enough to justify writing &lt;strong&gt;runbooks&lt;/strong&gt; and running &lt;strong&gt;failure drills&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;If a lab can survive those constraints, the skills transfer to almost any serious engineering org — fintech or not.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  The product: TNP Pay
&lt;/h3&gt;

&lt;p&gt;A small digital wallet app with three components:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tnp-pay-web&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Frontend — Nginx serving static assets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tnp-pay-api&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Backend service — connects to the database&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tnp-pay-db&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;PostgreSQL — also used for migration practice with Flyway&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;It's deliberately simple. The point was never to build a complicated app — it's to have &lt;em&gt;something real&lt;/em&gt; moving through the pipeline, so every tool in the lab has an actual job to do instead of sitting there as a checkbox.&lt;/p&gt;




&lt;h2&gt;
  
  
  The team that doesn't exist (but shapes everything)
&lt;/h2&gt;

&lt;p&gt;Here's a confession: TNP Technologies has no employees. It's just me, one laptop, and a lot of &lt;code&gt;kubectl apply&lt;/code&gt;. But the moment I started setting up RBAC, I ran into the same wall every solo builder hits — &lt;strong&gt;"admin for everything" isn't a security model, it's the absence of one.&lt;/strong&gt; You can't design real access control for a company of one, because there's nothing to control access &lt;em&gt;from&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;So I invented an org chart. Six roles, on paper, with nobody behind most of them:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Team&lt;/th&gt;
&lt;th&gt;Responsibility&lt;/th&gt;
&lt;th&gt;Access level&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Platform Engineering&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Owns infrastructure&lt;/td&gt;
&lt;td&gt;Cluster-admin, GitLab Owner&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Payment Engineering&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Ships TNP Pay to dev/staging&lt;/td&gt;
&lt;td&gt;Developer, namespace-scoped&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;QA/QE Team&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Owns test automation &amp;amp; quality gates&lt;/td&gt;
&lt;td&gt;Read-only on SonarQube reports&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Security Team&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Owns vulnerability scanning &amp;amp; policy&lt;/td&gt;
&lt;td&gt;Read-only on Trivy/gitleaks, manages OPA policy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SRE On-call&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Handles incidents, keeps the lights on&lt;/td&gt;
&lt;td&gt;Read-only on Prometheus/Grafana, break-glass only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Release Manager&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Approves production deploys&lt;/td&gt;
&lt;td&gt;Approve-only, no direct deploy rights&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A few of these were tempting to merge. QA and Security look like the same "quality" bucket at first glance — until you remember they answer different questions. QA asks &lt;em&gt;"does this work?"&lt;/em&gt; Security asks &lt;em&gt;"can this be abused?"&lt;/em&gt; Different concerns, different owners, in any compliance-driven org. Fold them together and you've quietly decided that a working feature and a secure feature are the same thing. They're not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Release Manager&lt;/strong&gt; was the role I almost cut, and glad I didn't. The whole point of that seat is uncomfortable by design: the person who writes the infrastructure code should &lt;em&gt;not&lt;/em&gt; be the person who waves it into production. Merge those two hats and you've built a system where the fastest way to ship a mistake is to be really good at your job.&lt;/p&gt;

&lt;p&gt;None of this changes what commands I type. I'm still the one running every playbook. But designing &lt;em&gt;as if&lt;/em&gt; six different people with six different incentives were watching over my shoulder turned RBAC from a checkbox — &lt;code&gt;verbs: ["*"]&lt;/code&gt;, ship it — into an actual design problem: &lt;strong&gt;who should be able to do what, and why.&lt;/strong&gt; That question doesn't go away just because the org chart is fictional.&lt;/p&gt;




&lt;h2&gt;
  
  
  What the stack looks like
&lt;/h2&gt;

&lt;p&gt;The whole lab runs on a &lt;strong&gt;single Windows machine&lt;/strong&gt; — 64GB RAM, VMware Workstation Pro, no cloud dependency for the core learning loop.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Windows Host (64GB RAM, VMware Workstation Pro)
│
├── devbox      Docker · k3d · Terraform · Ansible
│               Prometheus · Grafana · Loki
│
├── cicd        GitLab CE · Harbor · SonarQube
│
└── 4x Linux VMs   Ansible targets
    ├── rocky-01 / rocky-02    Rocky Linux 10
    └── ubuntu-01 / ubuntu-02  Ubuntu 26.04 LTS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The four Ansible targets are deliberately &lt;strong&gt;not identical&lt;/strong&gt; — two Rocky, two Ubuntu — so playbooks have to actually handle differences: SELinux vs AppArmor, firewalld vs ufw, dnf vs apt.&lt;/p&gt;

&lt;p&gt;AWS enters the picture only where it has to: Terraform needs something real to provision against, and &lt;em&gt;"real"&lt;/em&gt; here means an actual cloud account, not another local container pretending to be one.&lt;/p&gt;




&lt;h2&gt;
  
  
  What this series covers
&lt;/h2&gt;

&lt;p&gt;Eleven parts, roughly in the order I actually built things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure Foundation&lt;/strong&gt; — hypervisor choice, VM sizing, networking&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-OS Configuration Management&lt;/strong&gt; — Ansible across Rocky and Ubuntu&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Self-Hosted CI/CD&lt;/strong&gt; — GitLab CE, Harbor, SonarQube&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kubernetes &amp;amp; Observability&lt;/strong&gt; — k3d, Prometheus, Grafana, Loki&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure as Code, with a Real Target&lt;/strong&gt; — Terraform against AWS, MinIO remote state&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shift-Left Security&lt;/strong&gt; — gitleaks, SAST, dependency &amp;amp; IaC scanning&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Supply Chain Security&lt;/strong&gt; — SBOM, image signing with Cosign, policy gates with OPA&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitOps at Scale&lt;/strong&gt; — ArgoCD, multi-environment promotion&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enterprise Practices&lt;/strong&gt; — RBAC, SLOs, runbooks, chaos engineering&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retrospective&lt;/strong&gt; — what actually worked, what I'd do differently, and what this lab still can't teach you&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each part stands on its own, but they build on each other the same way a real platform does — nothing here is a toy example rebuilt from scratch each time.&lt;/p&gt;




&lt;h2&gt;
  
  
  What this series won't pretend to be
&lt;/h2&gt;

&lt;p&gt;This is a homelab, not a production system, and I'm not going to write as if it is. There's no real user traffic, no real incident history, no real compliance audit.&lt;/p&gt;

&lt;p&gt;What it &lt;em&gt;does&lt;/em&gt; give you is the &lt;strong&gt;shape&lt;/strong&gt; of how these pieces fit together — usually the hardest part to learn from documentation alone, because official docs explain one tool at a time and never show you the seams.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you're learning DevOps and tired of tutorials that stop the moment a &lt;code&gt;kubectl apply&lt;/code&gt; succeeds, this series is for the part that comes after that — where the real questions start.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;strong&gt;Next up: Part 1 — Infrastructure Foundation&lt;/strong&gt;&lt;br&gt;
Why I ended up on VMware Workstation instead of Hyper-V or nested ESXi, and how I sized four VMs against a single 64GB machine without any of them starving the others.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>kubernetes</category>
      <category>terraform</category>
      <category>homelab</category>
    </item>
  </channel>
</rss>
