<?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>Forem: Gaurav Tayade</title>
    <description>The latest articles on Forem by Gaurav Tayade (@gauravtayade11).</description>
    <link>https://forem.com/gauravtayade11</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2914327%2Fc1023d6b-003f-40df-9d4b-c9052df771d5.jpg</url>
      <title>Forem: Gaurav Tayade</title>
      <link>https://forem.com/gauravtayade11</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/gauravtayade11"/>
    <language>en</language>
    <item>
      <title>Stop Copy-Pasting kubectl Commands to Debug Pods</title>
      <dc:creator>Gaurav Tayade</dc:creator>
      <pubDate>Sat, 11 Apr 2026 06:48:22 +0000</pubDate>
      <link>https://forem.com/gauravtayade11/stop-copy-pasting-kubectl-commands-to-debug-pods-d9b</link>
      <guid>https://forem.com/gauravtayade11/stop-copy-pasting-kubectl-commands-to-debug-pods-d9b</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Every time a pod crashes, you run the same 5 commands. There's a better way.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The pain
&lt;/h2&gt;

&lt;p&gt;It's 2 AM. Your on-call phone fires. A pod in production is crashing.&lt;/p&gt;

&lt;p&gt;You SSH in, open your terminal, and start the ritual:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; nxs-demo-bad
kubectl describe pod crash-loop-demo &lt;span class="nt"&gt;-n&lt;/span&gt; nxs-demo-bad
kubectl logs crash-loop-demo &lt;span class="nt"&gt;-n&lt;/span&gt; nxs-demo-bad &lt;span class="nt"&gt;--previous&lt;/span&gt;
kubectl get events &lt;span class="nt"&gt;-n&lt;/span&gt; nxs-demo-bad &lt;span class="nt"&gt;--sort-by&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'.lastTimestamp'&lt;/span&gt;
kubectl top pod crash-loop-demo &lt;span class="nt"&gt;-n&lt;/span&gt; nxs-demo-bad
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get walls of output. You scan through it manually. You try to piece together what went wrong. You copy the error into Google. You find a Stack Overflow answer from 2019.&lt;/p&gt;

&lt;p&gt;This is the reality for most engineers debugging Kubernetes. Not because they don't know what they're doing — but because the tooling makes you do all the work yourself.&lt;/p&gt;

&lt;p&gt;Here's what a real broken namespace looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; nxs-demo-bad

NAME              READY   STATUS             RESTARTS         AGE
crash-loop-demo   0/1     Error              68 &lt;span class="o"&gt;(&lt;/span&gt;5m20s ago&lt;span class="o"&gt;)&lt;/span&gt;   22h
image-pull-demo   0/1     ImagePullBackOff   0                22h
oom-demo          0/1     CrashLoopBackOff   95 &lt;span class="o"&gt;(&lt;/span&gt;30s ago&lt;span class="o"&gt;)&lt;/span&gt;     22h
pending-demo      0/1     Pending            0                22h
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4 pods broken. 4 different problems. Where do you even start?&lt;/p&gt;




&lt;h2&gt;
  
  
  What's actually happening
&lt;/h2&gt;

&lt;p&gt;When a pod crashes, the information you need is spread across three places:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Logs&lt;/strong&gt; — what the application printed before it died&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Events&lt;/strong&gt; — what Kubernetes did (pulled image, scheduled, killed)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Describe&lt;/strong&gt; — the pod spec, resource limits, exit codes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You have to gather all three, read them together, and mentally correlate them to find the root cause. For experienced engineers this takes 5-10 minutes. For developers who don't live in kubectl every day, it can take much longer.&lt;/p&gt;




&lt;h2&gt;
  
  
  The new way
&lt;/h2&gt;

&lt;p&gt;I built &lt;code&gt;nxs&lt;/code&gt; — an open-source CLI that does all of this in one command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nxs k8s debug &lt;span class="nt"&gt;--pod&lt;/span&gt; crash-loop-demo &lt;span class="nt"&gt;-n&lt;/span&gt; nxs-demo-bad
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. nxs automatically:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Fetches the pod logs (including &lt;code&gt;--previous&lt;/code&gt; for crashed containers)&lt;/li&gt;
&lt;li&gt;Fetches &lt;code&gt;kubectl describe&lt;/code&gt; output&lt;/li&gt;
&lt;li&gt;Sends both to AI for root cause analysis&lt;/li&gt;
&lt;li&gt;Returns: what broke, why, and exact fix commands&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's the &lt;strong&gt;real output&lt;/strong&gt; from running it against that broken pod:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;╔══════════════════════════════════════════════════════════╗
║  ⚡ nxs                                        v2.0.0  ║
║     Kubernetes deep-dive debugger                        ║
╚══════════════════════════════════════════════════════════╝

────────────────────────────────────────────────────────────
  ☸  KUBERNETES DETECTED
────────────────────────────────────────────────────────────

📋 SUMMARY

  The pod 'crash-loop-demo' is crashing in a loop due to an error
  in the container. The container exits with a non-zero exit code
  after failing to find a configuration file.

🔍 ROOT CAUSE

  1. The container exits with code 1 — the config file
     /etc/app/config.yaml does not exist inside the container.
  2. Kubernetes repeatedly restarts the container due to its
     restart policy, leading to CrashLoopBackOff.
  3. No ConfigMap or volume is mounted to provide the config file.

💡 FIX STEPS

  1. Ensure the required config file is mounted via a ConfigMap.
  2. Verify the container command matches what exists in the image.
  3. Adjust restart policy or fix the application error handling.

💻 REMEDIATION COMMANDS

  ┌─ shell ────────────────────────────────────────────────────────┐
  │ 1. kubectl describe pod crash-loop-demo -n nxs-demo-bad        │
  │ 2. kubectl logs crash-loop-demo -n nxs-demo-bad                │
  │ 3. kubectl exec -it crash-loop-demo -n nxs-demo-bad -- /bin/sh │
  └─────────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Plain English. Root cause numbered. Commands ready to copy.&lt;br&gt;
&lt;strong&gt;No manual log reading. No Googling. No Stack Overflow.&lt;/strong&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  It also works with piped logs
&lt;/h2&gt;

&lt;p&gt;If you already have the logs, just pipe them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# From a file&lt;/span&gt;
nxs k8s debug pod-error.log

&lt;span class="c"&gt;# From kubectl directly&lt;/span&gt;
kubectl logs my-pod &lt;span class="nt"&gt;--previous&lt;/span&gt; | nxs k8s debug &lt;span class="nt"&gt;--stdin&lt;/span&gt;

&lt;span class="c"&gt;# Full describe + logs combined&lt;/span&gt;
kubectl describe pod my-pod | nxs k8s debug &lt;span class="nt"&gt;--stdin&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Debug an entire deployment at once
&lt;/h2&gt;

&lt;p&gt;Got a deployment with 3 replicas all crashing? Instead of checking each pod:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nxs k8s debug &lt;span class="nt"&gt;--deployment&lt;/span&gt; my-app &lt;span class="nt"&gt;-n&lt;/span&gt; production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;nxs fetches logs and describe from &lt;strong&gt;all pods&lt;/strong&gt; in the deployment concurrently and analyzes them together — so you get one diagnosis instead of three.&lt;/p&gt;




&lt;h2&gt;
  
  
  Works without an AI key
&lt;/h2&gt;

&lt;p&gt;No API key? No problem. nxs has a smart mock mode that pattern-matches common errors (CrashLoopBackOff, OOMKilled, ImagePullBackOff, Pending) and returns accurate responses without any AI call.&lt;/p&gt;

&lt;p&gt;To add a free Groq key (recommended — much more accurate):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nxs config &lt;span class="nt"&gt;--setup&lt;/span&gt;
&lt;span class="c"&gt;# Groq is free: console.groq.com&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @nextsight/nxs-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Requirements: Node.js 18+, kubectl configured&lt;/p&gt;




&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;This is article 1 in the &lt;strong&gt;"DevOps in 1 Command"&lt;/strong&gt; series.&lt;/p&gt;

&lt;p&gt;Next up: &lt;strong&gt;How I catch OOMKills before they happen in production&lt;/strong&gt; — using &lt;code&gt;nxs predict&lt;/code&gt; to surface at-risk pods before Kubernetes kills them.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;nxs is open source. Star it on GitHub: &lt;a href="https://github.com/gauravtayade11/nxs" rel="noopener noreferrer"&gt;https://github.com/gauravtayade11/nxs&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Install: &lt;code&gt;npm install -g @nextsight/nxs-cli&lt;/code&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>devops</category>
      <category>security</category>
    </item>
    <item>
      <title>Building a Production-Ready SonarQube Scanner Plugin for Devtron CI/CD</title>
      <dc:creator>Gaurav Tayade</dc:creator>
      <pubDate>Mon, 23 Mar 2026 11:06:14 +0000</pubDate>
      <link>https://forem.com/gauravtayade11/building-a-production-ready-sonarqube-scanner-plugin-for-devtron-cicd-1998</link>
      <guid>https://forem.com/gauravtayade11/building-a-production-ready-sonarqube-scanner-plugin-for-devtron-cicd-1998</guid>
      <description>&lt;h1&gt;
  
  
  Building a Production-Ready SonarQube Scanner Plugin for Devtron CI/CD
&lt;/h1&gt;

&lt;p&gt;How to build a reusable, secure, and language-agnostic SonarQube scanner plugin that enforces code quality gates across all application pipelines in Devtron.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Built a &lt;strong&gt;custom Devtron plugin&lt;/strong&gt; for SonarQube scanning&lt;/li&gt;
&lt;li&gt;Works across &lt;strong&gt;all languages&lt;/strong&gt; (Java, Python, JS, TS, Go)&lt;/li&gt;
&lt;li&gt;Enforces &lt;strong&gt;Quality Gates&lt;/strong&gt; and blocks deployments on failure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero token exposure&lt;/strong&gt; in pipeline logs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One plugin&lt;/strong&gt; reusable across all apps with minimal config&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;When managing multiple application pipelines using &lt;a href="https://devtron.ai" rel="noopener noreferrer"&gt;Devtron&lt;/a&gt; an open-source Kubernetes-native CI/CD platform, teams often need a consistent way to enforce &lt;strong&gt;code quality standards&lt;/strong&gt; across all applications without asking every team to set up SonarQube from scratch.&lt;/p&gt;

&lt;p&gt;The challenge? Devtron's native SonarQube plugin can have limitations. This post walks through building a custom production-ready, reusable plugin that solves these challenges.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Build a Custom Plugin
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Native plugin limitations&lt;/strong&gt; - The built-in Devtron SonarQube plugin may have authentication issues&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No modification access&lt;/strong&gt; - You cannot modify Devtron's native plugins&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reusability&lt;/strong&gt; - One plugin all teams can use without writing their own scripts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security&lt;/strong&gt; - Proper secret handling and token validation before every scan&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Architecture Overview
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Devtron CI Pipeline
        |
        |-- Pre-build Stage
        |   |-- SonarQube Scanner Plugin (custom)
        |       |-- Container Image  &amp;lt;- sonar-scanner binary
        |       |-- Shell Script     &amp;lt;- logic
        |       |-- sonar-project.properties &amp;lt;- per app repo
        |
        |-- Build Stage
        |   |-- Docker Image Build
        |
        |-- Post-build Stage
            |-- Deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; Separate the binary from the logic. The container image carries the sonar-scanner binary, while the shell script mounted at runtime by Devtron contains all the logic. This means you can update the script without rebuilding the image!&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  The Container Image
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; alpine:3.20&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;apk add &lt;span class="nt"&gt;--no-cache&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    curl unzip openjdk17-jre bash &lt;span class="se"&gt;\
&lt;/span&gt;    nodejs npm libstdc++ libgcc &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /var/cache/apk/&lt;span class="k"&gt;*&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;curl &lt;span class="nt"&gt;-sSLo&lt;/span&gt; /tmp/sonar.zip &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="s2"&gt;"https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-6.2.1.4610-linux-x64.zip"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    unzip &lt;span class="nt"&gt;-q&lt;/span&gt; /tmp/sonar.zip &lt;span class="nt"&gt;-d&lt;/span&gt; /opt &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;mv&lt;/span&gt; /opt/sonar-scanner-6.2.1.4610-linux-x64 /opt/sonar-scanner &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;rm&lt;/span&gt; /tmp/sonar.zip &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /opt/sonar-scanner/jre &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'s/use_embedded_jre=true/use_embedded_jre=false/'&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    /opt/sonar-scanner/bin/sonar-scanner

&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; JAVA_HOME=/usr/lib/jvm/java-17-openjdk&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; PATH="/opt/sonar-scanner/bin:/usr/lib/jvm/java-17-openjdk/bin:$PATH"&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; SONAR_SCANNER_OPTS="-Dsonar.nodejs.executable=/usr/bin/node"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Common Gotchas
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Alpine needs BOTH libstdc++ AND libgcc&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Missing either causes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;Error loading shared library libstdc++.so.6: No such file or directory
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Never use $(which node) in ENV instruction&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Wrong&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; SONAR_SCANNER_OPTS="-Dsonar.nodejs.executable=$(which node)"&lt;/span&gt;

&lt;span class="c"&gt;# Correct&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; SONAR_SCANNER_OPTS="-Dsonar.nodejs.executable=/usr/bin/node"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The Shell Script
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Script Flow
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Strip trailing slash from URL
2. Validate required variables
3. Security checks (token format, HTTPS)
4. Connectivity check
5. Token authentication via API
6. Source code validation
7. Run sonar-scanner
8. Check Quality Gate via API
9. Report status in logs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Security Handling
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Never print the token&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; +x

&lt;span class="c"&gt;# Validate token BEFORE scan&lt;/span&gt;
&lt;span class="nv"&gt;AUTH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;--silent&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SONAR_TOKEN&lt;/span&gt;&lt;span class="s2"&gt;:"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SONAR_HOST_URL&lt;/span&gt;&lt;span class="s2"&gt;/api/authentication/validate"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$AUTH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="s1"&gt;'"valid":true'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Token authentication FAILED!"&lt;/span&gt;
  &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# Filter token from scanner output&lt;/span&gt;
/opt/sonar-scanner/bin/sonar-scanner &lt;span class="nv"&gt;$SCANNER_ARGS&lt;/span&gt; 2&amp;gt;&amp;amp;1 | &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"sonar.token"&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="s2"&gt;"sonar.login"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Fix Trailing Slash Issue
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;SonarQube returns HTML instead of JSON when the URL has a trailing slash causing auth to fail even with a valid token!&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Always strip trailing slash first&lt;/span&gt;
&lt;span class="nv"&gt;SONAR_HOST_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SONAR_HOST_URL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s:/*$::'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Quality Gate Control
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# FAIL_ON_QUALITY_GATE=false is useful for onboarding legacy projects&lt;/span&gt;
&lt;span class="nv"&gt;FAIL_ON_QUALITY_GATE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;FAIL_ON_QUALITY_GATE&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="nv"&gt;true&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$QG_STATUS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ERROR"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$FAIL_ON_QUALITY_GATE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"false"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"WARNING: Quality Gate failed but pipeline continues"&lt;/span&gt;
  &lt;span class="k"&gt;else
    &lt;/span&gt;&lt;span class="nb"&gt;exit &lt;/span&gt;1
  &lt;span class="k"&gt;fi
fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Devtron Plugin Configuration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Plugin Form Settings
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Task Name&lt;/td&gt;
&lt;td&gt;SonarQube Scanner with Quality Gate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Plugin ID&lt;/td&gt;
&lt;td&gt;sonarqube-scanner-quality-gate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Version&lt;/td&gt;
&lt;td&gt;1.0.0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mount Code At&lt;/td&gt;
&lt;td&gt;/scripts/sonar-scan.sh&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Command&lt;/td&gt;
&lt;td&gt;/bin/sh&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Args&lt;/td&gt;
&lt;td&gt;/scripts/sonar-scan.sh&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mount Code to Container&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Input Variables
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Variable&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Required&lt;/th&gt;
&lt;th&gt;Default&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SONAR_TOKEN&lt;/td&gt;
&lt;td&gt;Secret&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SONAR_HOST_URL&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SONAR_PROJECT_KEY&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SONAR_PROJECT_NAME&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Same as key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SONAR_SOURCES&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;/sourcecode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SONAR_JAVA_BINARIES&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SONAR_EXCLUSIONS&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;BRANCH_NAME&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;QUALITY_GATE_TIMEOUT&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;300&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FAIL_ON_QUALITY_GATE&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;true&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Always use Secret type for SONAR_TOKEN&lt;/strong&gt; - tokens appear in plain text in logs when using String type!&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Per-App Configuration
&lt;/h2&gt;

&lt;p&gt;Each app just needs one file added to its repo root.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;JavaScript/TypeScript:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;sonar.projectKey&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;my-app&lt;/span&gt;
&lt;span class="py"&gt;sonar.projectName&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;My App&lt;/span&gt;
&lt;span class="py"&gt;sonar.sources&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;src&lt;/span&gt;
&lt;span class="py"&gt;sonar.exclusions&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;**/node_modules/**,**/coverage/**,**/*.test.js&lt;/span&gt;
&lt;span class="py"&gt;sonar.javascript.lcov.reportPaths&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;coverage/lcov.info&lt;/span&gt;
&lt;span class="py"&gt;sonar.sourceEncoding&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;UTF-8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Python:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;sonar.projectKey&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;my-python-app&lt;/span&gt;
&lt;span class="py"&gt;sonar.projectName&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;My Python App&lt;/span&gt;
&lt;span class="py"&gt;sonar.language&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;py&lt;/span&gt;
&lt;span class="py"&gt;sonar.python.version&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;3&lt;/span&gt;
&lt;span class="py"&gt;sonar.sources&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;.&lt;/span&gt;
&lt;span class="py"&gt;sonar.exclusions&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;**/__pycache__/**,**/*.pyc,**/venv/**&lt;/span&gt;
&lt;span class="py"&gt;sonar.python.coverage.reportPaths&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;coverage.xml&lt;/span&gt;
&lt;span class="py"&gt;sonar.sourceEncoding&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;UTF-8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Java Maven:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;sonar.projectKey&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;my-java-app&lt;/span&gt;
&lt;span class="py"&gt;sonar.projectName&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;My Java App&lt;/span&gt;
&lt;span class="py"&gt;sonar.sources&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;src/main/java&lt;/span&gt;
&lt;span class="py"&gt;sonar.java.binaries&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;target/classes&lt;/span&gt;
&lt;span class="py"&gt;sonar.tests&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;src/test/java&lt;/span&gt;
&lt;span class="py"&gt;sonar.sourceEncoding&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;UTF-8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Project Onboarding Automation
&lt;/h2&gt;

&lt;p&gt;For each new project we automate everything via SonarQube API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sh sonar-onboard.sh

&lt;span class="c"&gt;# Output:&lt;/span&gt;
&lt;span class="c"&gt;# Project created: my-app&lt;/span&gt;
&lt;span class="c"&gt;# Group created: my-app-developers&lt;/span&gt;
&lt;span class="c"&gt;# User added to group&lt;/span&gt;
&lt;span class="c"&gt;# Permissions assigned&lt;/span&gt;
&lt;span class="c"&gt;# Project set to PRIVATE&lt;/span&gt;
&lt;span class="c"&gt;#&lt;/span&gt;
&lt;span class="c"&gt;# CI TOKEN: sqa_xxxxxxxxxxxxx&lt;/span&gt;
&lt;span class="c"&gt;# Add to Devtron as SONAR_TOKEN secret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Challenges and Solutions
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Challenge&lt;/th&gt;
&lt;th&gt;Solution&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Native plugin auth issues&lt;/td&gt;
&lt;td&gt;Custom shell script plugin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Token exposed in logs&lt;/td&gt;
&lt;td&gt;set +x and grep filter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trailing slash in URL&lt;/td&gt;
&lt;td&gt;Strip with sed first&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alpine missing C++ libs&lt;/td&gt;
&lt;td&gt;Add libstdc++ and libgcc&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Node.js path issue&lt;/td&gt;
&lt;td&gt;Hardcode /usr/bin/node&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Quality Gate blocking new projects&lt;/td&gt;
&lt;td&gt;FAIL_ON_QUALITY_GATE=false&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;/bin/sh vs /bin/bash&lt;/td&gt;
&lt;td&gt;Full POSIX sh compatible script&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;One plugin reusable across all apps and languages&lt;/li&gt;
&lt;li&gt;Zero token exposure in pipeline logs&lt;/li&gt;
&lt;li&gt;Consistent quality gates across all teams&lt;/li&gt;
&lt;li&gt;New app onboarded in under 10 minutes&lt;/li&gt;
&lt;li&gt;Flexible gradual adoption with FAIL_ON_QUALITY_GATE&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Coverage reports (JaCoCo, pytest-cov, lcov)&lt;/li&gt;
&lt;li&gt;Branch and PR analysis&lt;/li&gt;
&lt;li&gt;Slack notifications on Quality Gate failure&lt;/li&gt;
&lt;li&gt;Custom Grafana dashboard for scan trends&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.devtron.ai" rel="noopener noreferrer"&gt;Devtron Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/scanners/sonarscanner/" rel="noopener noreferrer"&gt;SonarQube Scanner CLI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://next.sonarqube.com/sonarqube/web_api" rel="noopener noreferrer"&gt;SonarQube API Reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.sonarsource.com/sonarqube/latest/user-guide/quality-gates/" rel="noopener noreferrer"&gt;SonarQube Quality Gates&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;If this helped you drop a reaction and share with your team!&lt;/p&gt;

</description>
      <category>devops</category>
      <category>devtron</category>
      <category>sonarqube</category>
      <category>cicd</category>
    </item>
    <item>
      <title>I got paranoid about online tools logging my secrets — so I built my own</title>
      <dc:creator>Gaurav Tayade</dc:creator>
      <pubDate>Wed, 18 Mar 2026 06:17:41 +0000</pubDate>
      <link>https://forem.com/gauravtayade11/i-got-paranoid-about-online-tools-logging-my-secrets-so-i-built-my-own-1j6o</link>
      <guid>https://forem.com/gauravtayade11/i-got-paranoid-about-online-tools-logging-my-secrets-so-i-built-my-own-1j6o</guid>
      <description>&lt;p&gt;A few months ago a teammate accidentally pasted production AWS credentials &lt;br&gt;
into an online JSON formatter. Nothing happened — but it could have.&lt;/p&gt;

&lt;p&gt;That moment stuck with me. How many times had I pasted a JWT, a .env file, &lt;br&gt;
or a Dockerfile into some random tool without thinking about it? Those sites &lt;br&gt;
are free because they can afford to be. Your data might be the product.&lt;/p&gt;

&lt;p&gt;So I stopped using them and built my own: &lt;strong&gt;DevsTool&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it is
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://devstool.vercel.app" rel="noopener noreferrer"&gt;DevsTool&lt;/a&gt; is a collection of 19 developer and &lt;br&gt;
DevOps utilities that run entirely in your browser. No backend, no accounts, &lt;br&gt;
no data collection. The only thing that ever leaves your machine is the URL &lt;br&gt;
you're on.&lt;/p&gt;

&lt;h2&gt;
  
  
  The tools I use most as a DevOps engineer
&lt;/h2&gt;

&lt;h3&gt;
  
  
  K8s Manifest Generator
&lt;/h3&gt;

&lt;p&gt;Fill in a form — name, image, replicas, resource limits, env vars — and get &lt;br&gt;
a ready-to-apply Deployment + Service YAML. Handles ConfigMap, Ingress, and &lt;br&gt;
HPA too. No more copying boilerplate from Stack Overflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  CIDR / Subnet Calculator
&lt;/h3&gt;

&lt;p&gt;Enter a CIDR block like &lt;code&gt;10.0.0.0/24&lt;/code&gt; and instantly see the network address, &lt;br&gt;
broadcast, first/last host, total IPs, and usable hosts. Has a binary &lt;br&gt;
visualizer showing which bits are network vs host, and an IP-in-range checker.&lt;br&gt;
Essential for VPC planning.&lt;/p&gt;

&lt;h3&gt;
  
  
  Secret Scanner
&lt;/h3&gt;

&lt;p&gt;Paste any text — code, config, logs — and it scans for 20+ credential &lt;br&gt;
patterns: AWS access keys, GitHub tokens, GCP service account keys, Azure &lt;br&gt;
connection strings, Stripe keys, Discord tokens, and more. All regex, all &lt;br&gt;
client-side.&lt;/p&gt;

&lt;h3&gt;
  
  
  Log Formatter
&lt;/h3&gt;

&lt;p&gt;Paste JSON logs and it parses them into a structured view with level badges, &lt;br&gt;
timestamps, and expandable JSON payloads. Filter by error/warn/info/debug, &lt;br&gt;
search across lines, and scroll horizontally for long lines. You can also &lt;br&gt;
upload a &lt;code&gt;.log&lt;/code&gt; file directly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dockerfile Linter
&lt;/h3&gt;

&lt;p&gt;Checks 12 best-practice rules: pinned base images, no &lt;code&gt;apt-get&lt;/code&gt; without &lt;br&gt;
&lt;code&gt;--no-install-recommends&lt;/code&gt;, COPY over ADD, non-root USER, and more.&lt;/p&gt;

&lt;h3&gt;
  
  
  Other tools
&lt;/h3&gt;

&lt;p&gt;JSON Formatter (Monaco editor), JWT Decoder, YAML Validator, ENV Parser, &lt;br&gt;
Diff Checker, Markdown Preview, Cron Builder, Git Command Builder, &lt;br&gt;
Base64/URL Encoder, UUID Generator, Timestamp Converter, Port Reference, &lt;br&gt;
HTTP Headers inspector.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it's built
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next.js 15&lt;/strong&gt; App Router, fully static except the HTTP Headers proxy&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tailwind CSS v4&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monaco Editor&lt;/strong&gt; (via CDN to avoid Turbopack worker bundling issues)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;⌘K command palette&lt;/strong&gt; for jumping between tools instantly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shareable links&lt;/strong&gt; — tool state is base64url-encoded in the URL, 
no server involved&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The secret scanner is just a list of compiled regexes run against the input &lt;br&gt;
on every keystroke. The K8s generator is a form that builds a YAML string — &lt;br&gt;
no server, no templating engine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why client-side matters
&lt;/h2&gt;

&lt;p&gt;When you paste a JWT into a tool, you're potentially exposing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The algorithm and signing key hint&lt;/li&gt;
&lt;li&gt;User IDs, roles, and permissions encoded in the payload&lt;/li&gt;
&lt;li&gt;Token expiry (useful for timing attacks)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you paste a .env file, you're potentially exposing every secret your &lt;br&gt;
app uses. Running these tools in the browser means the data never travels &lt;br&gt;
over a network. There's nothing to intercept, nothing to log.&lt;/p&gt;




&lt;p&gt;The project is open source: &lt;a href="https://github.com/gauravtayade11/devstool" rel="noopener noreferrer"&gt;github.com/gauravtayade11/devstool&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Live: &lt;a href="https://devstool.vercel.app" rel="noopener noreferrer"&gt;devstool.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Would love feedback — especially on what DevOps tools you'd want added next.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>programming</category>
      <category>devops</category>
    </item>
    <item>
      <title>I Built an Open-Source Kubernetes Dashboard - Here's What I Learned</title>
      <dc:creator>Gaurav Tayade</dc:creator>
      <pubDate>Tue, 02 Dec 2025 05:24:34 +0000</pubDate>
      <link>https://forem.com/gauravtayade11/title-i-built-an-open-source-kubernetes-dashboard-heres-what-i-learned-4n7k</link>
      <guid>https://forem.com/gauravtayade11/title-i-built-an-open-source-kubernetes-dashboard-heres-what-i-learned-4n7k</guid>
      <description>&lt;h2&gt;
  
  
  Why Another K8s Dashboard?
&lt;/h2&gt;

&lt;p&gt;I know what you're thinking - "There's already Lens, K9s, Rancher..."&lt;/p&gt;

&lt;p&gt;Here's the thing: I wanted something that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Runs in a browser (no local installation)&lt;/li&gt;
&lt;li&gt;Has built-in safety guards (block dangerous commands)&lt;/li&gt;
&lt;li&gt;Deploys easily to the cluster itself&lt;/li&gt;
&lt;li&gt;Is completely open-source&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So I built &lt;strong&gt;NexOps&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 30-Second Demo
&lt;/h2&gt;

&lt;p&gt;git clone &lt;a href="https://github.com/gauravtayade11/nexops.git" rel="noopener noreferrer"&gt;https://github.com/gauravtayade11/nexops.git&lt;/a&gt;&lt;br&gt;
docker-compose up -d&lt;/p&gt;
&lt;h2&gt;
  
  
  Open &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;That's it. You're in.&lt;/p&gt;
&lt;h2&gt;
  
  
  What Makes It Different
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. Browser-Based kubectl with Safety Guards
&lt;/h3&gt;

&lt;p&gt;Run kubectl commands in your browser, but dangerous ones are blocked:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;dangerous_patterns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;delete --all&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;delete namespace&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;--force --grace-period=0&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;rm -rf /&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No more accidental cluster wipes.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Real-Time Everything
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Live cluster health&lt;/li&gt;
&lt;li&gt;Streaming pod logs&lt;/li&gt;
&lt;li&gt;Container exec sessions&lt;/li&gt;
&lt;li&gt;Event monitoring&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Team-Friendly
&lt;/h3&gt;

&lt;p&gt;Give developers cluster visibility without:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Installing kubectl locally&lt;/li&gt;
&lt;li&gt;Sharing kubeconfig files&lt;/li&gt;
&lt;li&gt;Full admin access&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Technical Challenges
&lt;/h2&gt;

&lt;p&gt;The hardest part? Making it work with Docker Desktop's Kubernetes.&lt;/p&gt;

&lt;p&gt;When your app runs in a container, &lt;code&gt;localhost:6443&lt;/code&gt; refers to the container, not your Mac. The fix: use &lt;code&gt;kubernetes.docker.internal&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tech Stack
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Backend&lt;/td&gt;
&lt;td&gt;FastAPI (Python 3.11)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Frontend&lt;/td&gt;
&lt;td&gt;React 18 + TypeScript&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Styling&lt;/td&gt;
&lt;td&gt;Tailwind CSS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Container&lt;/td&gt;
&lt;td&gt;Docker + nginx&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] WebSocket for real-time logs&lt;/li&gt;
&lt;li&gt;[ ] Multi-cluster support&lt;/li&gt;
&lt;li&gt;[ ] RBAC integration&lt;/li&gt;
&lt;li&gt;[ ] Helm chart UI&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try It Out
&lt;/h2&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/gauravtayade11/nexops" rel="noopener noreferrer"&gt;https://github.com/gauravtayade11/nexops&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Star ⭐ if you find it useful!&lt;/p&gt;




&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm3rqi0cl0urruuxlfa5e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm3rqi0cl0urruuxlfa5e.png" alt="NexOps Dashboard" width="800" height="391"&gt;&lt;/a&gt;&lt;br&gt;
What K8s tools do you use? I'd love to hear in the comments!&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>kubernetes</category>
      <category>devops</category>
      <category>opensource</category>
      <category>python</category>
    </item>
    <item>
      <title>Automating PostgreSQL Backups on Kubernetes with CronJobs &amp; Persistent Storage</title>
      <dc:creator>Gaurav Tayade</dc:creator>
      <pubDate>Tue, 01 Apr 2025 06:21:02 +0000</pubDate>
      <link>https://forem.com/gauravtayade11/automating-postgresql-backups-on-kubernetes-with-cronjobs-persistent-storage-2k6f</link>
      <guid>https://forem.com/gauravtayade11/automating-postgresql-backups-on-kubernetes-with-cronjobs-persistent-storage-2k6f</guid>
      <description>&lt;h2&gt;
  
  
  Automate PostgreSQL Database Backups in Kubernetes with CronJobs and Azure File Share
&lt;/h2&gt;

&lt;p&gt;Tired of manually backing up your PostgreSQL database? Automate the process using Kubernetes CronJobs, ConfigMaps, Persistent Volumes, and a lightweight PostgreSQL client Docker image.&lt;/p&gt;

&lt;p&gt;In this step-by-step guide, you’ll learn how to:&lt;/p&gt;

&lt;p&gt;✅ Create a Docker image with postgresql-client to perform backups.&lt;br&gt;&lt;br&gt;
✅ Use Kubernetes ConfigMaps to manage your backup script.&lt;br&gt;&lt;br&gt;
✅ Set up Persistent Volumes (PV &amp;amp; PVC) for storage.&lt;br&gt;&lt;br&gt;
✅ Automate backups using CronJobs with retention policies.&lt;/p&gt;


&lt;h2&gt;
  
  
  🛠 Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before getting started, ensure you have:&lt;/p&gt;

&lt;p&gt;✔ A Kubernetes cluster on Azure Kubernetes Service (AKS) or another Kubernetes environment.&lt;br&gt;&lt;br&gt;
✔ kubectl installed and configured.&lt;br&gt;&lt;br&gt;
✔ A running PostgreSQL database in Kubernetes.&lt;br&gt;&lt;br&gt;
✔ Azure CLI installed for managing Azure resources.&lt;br&gt;&lt;br&gt;
✔ Docker installed to build and push images.&lt;br&gt;&lt;br&gt;
✔ A DockerHub or private container registry to store the backup image.&lt;br&gt;&lt;br&gt;
✔ Azure File Share created for storing backups persistently.  &lt;/p&gt;

&lt;p&gt;💡 Azure File Share will be used as persistent storage for backups.&lt;/p&gt;

&lt;p&gt;Let’s get started! 🚀&lt;/p&gt;


&lt;h2&gt;
  
  
  💡 Why Automate PostgreSQL Backups?
&lt;/h2&gt;

&lt;p&gt;Manual backups are risky — you might forget, or worse, data loss could occur before you act. With this Kubernetes-native solution, backups run automatically on a schedule, ensuring:&lt;/p&gt;

&lt;p&gt;✔ &lt;strong&gt;Reliability&lt;/strong&gt; — No missed backups!&lt;br&gt;&lt;br&gt;
✔ &lt;strong&gt;Security&lt;/strong&gt; — Stored in Persistent Volumes (PVC).&lt;br&gt;&lt;br&gt;
✔ &lt;strong&gt;Efficiency&lt;/strong&gt; — Old backups are deleted after 7 days.&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;🔧 Step 1: Build &amp;amp; Push the PostgreSQL Backup Docker Image&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We’ll create a lightweight Docker image that only installs postgresql-client. This avoids unnecessary overhead from a full PostgreSQL installation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📌 Dockerfile&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Use the official Ubuntu base image&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; ubuntu:latest  &lt;/span&gt;
&lt;span class="c"&gt;# Install PostgreSQL client&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; postgresql-client &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    apt-get clean &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /var/lib/apt/lists/&lt;span class="k"&gt;*&lt;/span&gt;  
&lt;span class="c"&gt;# Set default command  &lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["psql", "--version"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🛠 Build &amp;amp; Push the Image&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build -t your-dockerhub-username/postgres-backup:latest .
docker push your-dockerhub-username/postgres-backup:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🔹 Replace your-dockerhub-username with your actual DockerHub username.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Create Persistent Storage for Backups (PV &amp;amp; PVC)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We’ll store backups in an Azure File Share-backed Persistent Volume (PV &amp;amp; PVC).&lt;/p&gt;

&lt;p&gt;📌 &lt;strong&gt;PersistentVolume (PV)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: PersistentVolume
metadata:
  name: postgresql-backup-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  azureFile:
    secretName: ""  # Add your secret here
    secretNamespace: "" 
    shareName: ""  # Add your Azure File Share name here
    readOnly: false

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;📌 PersistentVolumeClaim (PVC)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgresql-backup-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 10Gi
  volumeName: postgresql-backup-pv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;🔹 Modify shareName and secretName based on your Azure setup.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Apply these:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f pv.yaml
kubectl apply -f pvc.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;📜 Step 3: Create ConfigMap for Backup Script&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We need to mount the backup.sh script inside the CronJob container. Instead of hardcoding it, let’s use a ConfigMap.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📌 backup.sh (Backup Script)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash
NAMESPACE=${NAMESPACE:-"default"}
POSTGRES_SVC=${POSTGRES_SVC}
POSTGRES_USER=${POSTGRES_USER}
POSTGRES_DB=${POSTGRES_DB}
BACKUP_DIR="/backup"
DATE=$(date +"%Y-%m-%d")
BACKUP_FILE="${BACKUP_DIR}/${POSTGRES_DB}_${DATE}.sql"
TAR_FILE="${BACKUP_DIR}/${POSTGRES_DB}_${DATE}.tar.gz"
POSTGRES_PASS=${POSTGRES_PASS}
# Perform the backup
PGPASSWORD="$POSTGRES_PASS" pg_dump -h "$POSTGRES_SVC" -U "$POSTGRES_USER" -d "$POSTGRES_DB" -F c -f "$BACKUP_FILE"
# Compress the backup
if [ $? -eq 0 ]; then
  tar -czf "$TAR_FILE" -C "$BACKUP_DIR" "$(basename "$BACKUP_FILE")"
  rm -f "$BACKUP_FILE"
  echo "Backup completed: $TAR_FILE"
else
  echo "Backup failed!"
  exit 1
fi
# Delete backups older than 7 days
find "$BACKUP_DIR" -type f -name "${POSTGRES_DB}_*.tar.gz" -mtime +7 -exec rm -f {} \;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;📌 Create ConfigMap&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;kubectl create configmap backup-script --from-file=backup.sh&lt;/code&gt;&lt;br&gt;
🔹 This mounts backup.sh in the CronJob without modifying the container.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⏳ Step 4: Automate Backups with a Kubernetes CronJob&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The CronJob runs the backup script every night at 12:30 AM(UTC).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📌 CronJob YAML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: batch/v1
kind: CronJob
metadata:
  name: postgresql-backup
spec:
  schedule: "30 0 * * *"  # Runs daily at 12:30 AM UTC
  successfulJobsHistoryLimit: 1
  failedJobsHistoryLimit: 1
  jobTemplate:
    spec:
      template:
        spec:
          containers:
            - name: postgresql-backup
              image: your-dockerhub-username/postgres-backup:latest   #update the values
              imagePullPolicy: IfNotPresent
              command: ["/bin/sh", "-c"]
              args:
                - |
                  cp /scripts/backup.sh /tmp/backup.sh
                  chmod +x /tmp/backup.sh
                  until pg_isready -h "$POSTGRES_SVC" -U "$POSTGRES_USER"; do
                    echo "Waiting for PostgreSQL to be ready..."
                    sleep 5
                  done
                  echo "Running backup script..."
                  /tmp/backup.sh
              env:
                - name: POSTGRES_SVC
                  value: "your-postgres-service"   #update the values
                - name: POSTGRES_USER
                  valueFrom:
                    secretKeyRef:
                      name: your-secret        #update the values
                      key: POSTGRES_USER
                - name: POSTGRES_PASS
                  valueFrom:
                    secretKeyRef:
                      name: your-secret        #update the values
                      key: POSTGRES_PASSWORD
                - name: POSTGRES_DB
                  value: "your-database"       #update the values
              volumeMounts:
                - name: backup
                  mountPath: /backup
                - name: script-volume
                  mountPath: /scripts
          restartPolicy: OnFailure
          volumes:
            - name: backup
              persistentVolumeClaim:
                claimName: postgresql-backup-pvc
            - name: script-volume
              configMap:
                name: backup-script

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🔹 Replace your-dockerhub-username and your-postgres-service with actual values.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🛠 Apply CronJob&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;kubectl apply -f cronjob.yaml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;🚀 Wrapping Up&lt;/p&gt;

&lt;p&gt;Congratulations! 🎉 You have successfully automated PostgreSQL backups on Kubernetes using:&lt;/p&gt;

&lt;p&gt;✔ Dockerized PostgreSQL client for backup execution.&lt;/p&gt;

&lt;p&gt;✔ ConfigMaps to manage scripts.&lt;/p&gt;

&lt;p&gt;✔ Persistent Storage (PV &amp;amp; PVC) to retain backups.&lt;/p&gt;

&lt;p&gt;✔ CronJobs to schedule automated backups.&lt;/p&gt;

&lt;p&gt;💬 What’s Next?&lt;/p&gt;

&lt;p&gt;Want to take your PostgreSQL backup automation to the next level?&lt;br&gt;&lt;br&gt;
&lt;a href="https://www.fiverr.com/s/99Ab3LE" rel="noopener noreferrer"&gt;Hire me on Fiverr&lt;/a&gt; for customized solutions tailored to your needs!&lt;/p&gt;

&lt;p&gt;Have any questions or improvements? Drop a comment below!&lt;br&gt;
🔥 Have you automated PostgreSQL backups yet? Let me know in the comments! 🚀 &lt;/p&gt;

</description>
      <category>azure</category>
      <category>automation</category>
      <category>backup</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Automating EKS Deployment with Terraform: A Step-by-Step Guide</title>
      <dc:creator>Gaurav Tayade</dc:creator>
      <pubDate>Wed, 05 Mar 2025 17:40:49 +0000</pubDate>
      <link>https://forem.com/gauravtayade11/automating-eks-deployment-with-terraform-a-step-by-step-guide-3em</link>
      <guid>https://forem.com/gauravtayade11/automating-eks-deployment-with-terraform-a-step-by-step-guide-3em</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Introduction&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Managing Kubernetes clusters on AWS can be complex, but Terraform simplifies infrastructure provisioning. In this blog, I’ll walk you through how I automated the deployment of an &lt;strong&gt;EKS cluster&lt;/strong&gt; with &lt;strong&gt;IAM roles, node groups, and an ALB controller&lt;/strong&gt; using Terraform.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Why Terraform for EKS?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Terraform provides &lt;strong&gt;Infrastructure as Code (IaC)&lt;/strong&gt;, making infrastructure repeatable and scalable. By using Terraform to deploy EKS, you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Avoid manual configurations&lt;/li&gt;
&lt;li&gt;Ensure consistency across environments&lt;/li&gt;
&lt;li&gt;Automate infrastructure creation and scaling&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Project Overview&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This Terraform script accomplishes the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creates an &lt;strong&gt;IAM role&lt;/strong&gt; for the EKS control plane&lt;/li&gt;
&lt;li&gt;Deploys an &lt;strong&gt;EKS cluster&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Sets up an &lt;strong&gt;IAM role&lt;/strong&gt; for worker nodes&lt;/li&gt;
&lt;li&gt;Configures an &lt;strong&gt;EKS node group&lt;/strong&gt; with private subnets&lt;/li&gt;
&lt;li&gt;Adds an &lt;strong&gt;SSH key pair&lt;/strong&gt; for remote access&lt;/li&gt;
&lt;li&gt;Deploys an &lt;strong&gt;AWS Load Balancer Controller&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Project Structure&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;To keep the Terraform code modular, we will create a separate &lt;strong&gt;vars.tf&lt;/strong&gt; file to store all the required variables.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Directory Structure:&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;terraform-eks/
│-- main.tf
│-- variables.tf
│-- outputs.tf
│-- terraform.tfvars
│-- alb-ing-iam_policy.json
│-- providers.tf
|-- alb-ingress.tf
**
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Terraform Script Breakdown&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. Create a Variables File (variables.tf)&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"aws_region"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"AWS Region"&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"vpc_id"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nx"&gt;type&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
   &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"AWS VPC Id"&lt;/span&gt;
   &lt;span class="nx"&gt;sensitive&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"aws_private_subnets"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;type&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"List of Subnets"&lt;/span&gt;
    &lt;span class="nx"&gt;sensitive&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"cluster_version"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"EKS Cluster Version"&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;1.31&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;2. Define Terraform Variables File (terraform.tfvars)&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;aws_region&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;
&lt;span class="nx"&gt;vpc_id&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"vpc-************"&lt;/span&gt;
&lt;span class="nx"&gt;aws_private_subnets&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_private_subnets&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"private-subnet-1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"private-subnet-1"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nx"&gt;cluster_version&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;1.31&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;3. Defining Local Variables in main.tf&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;locals&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"eks-demo"&lt;/span&gt;
  &lt;span class="nx"&gt;common_tag&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Env&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Dev"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;4. Creating IAM Policy for ALB Ingress Controller&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_policy"&lt;/span&gt; &lt;span class="s2"&gt;"alb_ingress_policy"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${local.name}-ALBEksControllerPolicy"&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"IAM policy for ALB Ingress Controller"&lt;/span&gt;
  &lt;span class="nx"&gt;policy&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alb_ingress_policy_file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;5. Creating IAM Role for ALB Ingress Controller&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_role"&lt;/span&gt; &lt;span class="s2"&gt;"alb_ingress_role"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;               &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${local.name}-ALBEksControllerRole"&lt;/span&gt;
  &lt;span class="nx"&gt;assume_role_policy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsonencode&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;Version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;
    &lt;span class="nx"&gt;Statement&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;Effect&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
        &lt;span class="nx"&gt;Principal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;Service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"eks.amazonaws.com"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;Action&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"sts:AssumeRole"&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;6. Attaching IAM Policy to Role&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_iam_role_policy_attachment"&lt;/span&gt; &lt;span class="s2"&gt;"alb_ingress_policy_attachment"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;policy_arn&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_iam_policy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alb_ingress_policy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arn&lt;/span&gt;
  &lt;span class="nx"&gt;role&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_iam_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alb_ingress_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
  &lt;span class="nx"&gt;depends_on&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;aws_iam_policy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alb_ingress_policy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;aws_iam_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alb_ingress_role&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;7. Creating Kubernetes Service Account for ALB Controller&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"kubernetes_service_account"&lt;/span&gt; &lt;span class="s2"&gt;"alb_ingress_sa"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;metadata&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"alb-ingress-controller"&lt;/span&gt;
    &lt;span class="nx"&gt;namespace&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"kube-system"&lt;/span&gt;
    &lt;span class="nx"&gt;annotations&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"eks.amazonaws.com/role-arn"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_iam_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alb_ingress_role&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arn&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;depends_on&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="nx"&gt;aws_iam_role_policy_attachment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alb_ingress_policy_attachment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;aws_eks_cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eks_cluster&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;8. Deploying AWS Load Balancer Controller with Helm&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"helm_release"&lt;/span&gt; &lt;span class="s2"&gt;"alb_ingress_controller"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"alb-ingress-controller"&lt;/span&gt;
  &lt;span class="nx"&gt;repository&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"https://aws.github.io/eks-charts"&lt;/span&gt;
  &lt;span class="nx"&gt;chart&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"aws-load-balancer-controller"&lt;/span&gt;
  &lt;span class="nx"&gt;namespace&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"kube-system"&lt;/span&gt;
  &lt;span class="nx"&gt;set&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; 
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;name&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"clusterName"&lt;/span&gt;
      &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_eks_cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;eks_cluster&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;name&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"serviceAccount.create"&lt;/span&gt;
      &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"false"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;name&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"serviceAccount.name"&lt;/span&gt;
      &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;kubernetes_service_account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alb_ingress_sa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;name&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ingressClass"&lt;/span&gt;
      &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"alb"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;name&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"vpcID"&lt;/span&gt;
      &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vpc_id&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;name&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"region"&lt;/span&gt;
      &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aws_region&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;depends_on&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="nx"&gt;kubernetes_service_account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alb_ingress_sa&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Complete Deployment Flow&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Clone the repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/gauravtayade11/terraform-eks-alb.git

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Initialize Terraform:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Validate the configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform validate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply Terraform to create resources:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform apply &lt;span class="nt"&gt;-auto-approve&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the cluster:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws eks &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1 update-kubeconfig &lt;span class="nt"&gt;--name&lt;/span&gt; eks-demo-cluster
kubectl get nodes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;With this &lt;strong&gt;Terraform script&lt;/strong&gt;, we:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Created an &lt;strong&gt;EKS cluster&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Configured &lt;strong&gt;IAM roles and node groups&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Set up a &lt;strong&gt;scalable node group&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Installed an &lt;strong&gt;AWS Load Balancer Controller&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using Terraform ensures &lt;strong&gt;repeatability, scalability, and automation&lt;/strong&gt;. Feel free to &lt;strong&gt;try this setup&lt;/strong&gt; and modify it to match your needs. 🚀&lt;/p&gt;

&lt;p&gt;Check out the complete code on GitHub: &lt;a href="https://github.com/gauravtayade11/terraform-eks-alb" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let me know in the comments if you have any questions or improvements! 👇&lt;/p&gt;




</description>
      <category>aws</category>
      <category>devops</category>
      <category>terraform</category>
      <category>automation</category>
    </item>
  </channel>
</rss>
