<?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: Akash Singh</title>
    <description>The latest articles on Forem by Akash Singh (@skysingh04).</description>
    <link>https://forem.com/skysingh04</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%2F2305180%2F37572292-a0f8-48c5-8821-09ede2d8ad46.jpeg</url>
      <title>Forem: Akash Singh</title>
      <link>https://forem.com/skysingh04</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/skysingh04"/>
    <language>en</language>
    <item>
      <title>DO NOT AUTOSCALE : PBCTF RCA</title>
      <dc:creator>Akash Singh</dc:creator>
      <pubDate>Wed, 24 Sep 2025 17:35:11 +0000</pubDate>
      <link>https://forem.com/skysingh04/do-not-autoscale-pbctf-rca-1dcl</link>
      <guid>https://forem.com/skysingh04/do-not-autoscale-pbctf-rca-1dcl</guid>
      <description>&lt;h2&gt;
  
  
  The Incident
&lt;/h2&gt;

&lt;p&gt;On 02.08.25, during PBCTF 4.0 - our college club &lt;a href="https://www.linkedin.com/company/point-blank-d" rel="noopener noreferrer"&gt;Point Blank's&lt;/a&gt; flagship CTF competition - we experienced what every CTF organizer fears: a complete platform outage. For 35 agonizing minutes from 10:00AM to 10:35AM IST, Me and &lt;a href="https://x.com/govind_404" rel="noopener noreferrer"&gt;Govind&lt;/a&gt; tried bringing the service back up while 45-50 of our other teammates made memes and helped calm the revolting participants.&lt;/p&gt;

&lt;p&gt;The incident was not a complete outage as we had a backup ctfd deployment running on our own PB Server, pointing to a different DNS, to which we directed traffic. Sadly, the PB Server was not powerful enough to handle all 400 participants but it did take care of approximately half of them while the rest of PB Members distracted the other half set of participants. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Credits to our senior &lt;a href="https://www.linkedin.com/in/ashupdsce/" rel="noopener noreferrer"&gt;Ashutosh Pandey&lt;/a&gt; for the idea to keep a backup deployment ready.&lt;/p&gt;
&lt;/blockquote&gt;




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

&lt;p&gt;I am Akash Singh, a final year engineering student and Open Source Contributor from Bangalore.&lt;br&gt;
Here is my &lt;a href="https://www.linkedin.com/in/skysingh04/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, &lt;a href="https://github.com/SkySingh04" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; and &lt;a href="https://x.com/SkySingh04" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&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%2F4eayocft44kkbwoqpc8z.JPG" 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%2F4eayocft44kkbwoqpc8z.JPG" alt="Sky Singh" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I go by the name SkySingh04 online.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  Timeline of Events
&lt;/h2&gt;
&lt;h3&gt;
  
  
  T-0: The Calm Before the Storm
&lt;/h3&gt;

&lt;p&gt;The opening ceremony went great and we were ready to get the CTF Started. Both deployments were healthy and participants were logging on and getting ready for the CTF.&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%2F4hezkpjoalbxoutjvo5i.jpg" 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%2F4hezkpjoalbxoutjvo5i.jpg" alt=" " width="800" height="609"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our GCP Kubernetes cluster was a sweet deal, we spent 1000 INR to get 25000 INR in GCP credits and felt invincible with all that cloud power at our disposal.&lt;/p&gt;
&lt;h3&gt;
  
  
  T+5 minutes: "Let's Scale!"
&lt;/h3&gt;

&lt;p&gt;Traffic was picking up. In a moment of what seemed like devops big brain time (it wasn't), I decided to scale up our pods. After all, who doesn't love autoscaling? 25000 INR needs to be used afterall.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# What could possibly go wrong?&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;  &lt;span class="c1"&gt;# YOLO&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Me Chilling after &lt;strong&gt;""AutoSCAllINg""&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&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%2F868msbpus39r4867pywb.jpg" 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%2F868msbpus39r4867pywb.jpg" alt=" " width="800" height="781"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  T+10 minutes: The First Signs of Trouble
&lt;/h3&gt;

&lt;p&gt;New pods started spinning up. They attempted to run database migrations - standard procedure, right? Wrong. The pods immediately crashed with migration errors.&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%2Fzz09dkvnd7gdb9kqg1t9.JPG" 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%2Fzz09dkvnd7gdb9kqg1t9.JPG" alt=" " width="800" height="1422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  T+15 minutes: Panic Mode Activated
&lt;/h3&gt;

&lt;p&gt;Our initial hypothesis: "Must be a migration issue!"&lt;/p&gt;

&lt;p&gt;The night before, Govind said he ran some custom migrations. Maybe something was incompatible? In my big brain, I decided to delete all pods and start fresh.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl delete pods &lt;span class="nt"&gt;--all&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; ctfd
&lt;span class="c"&gt;# Famous last words: "This will fix it"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  T+16 minutes: Full Outage
&lt;/h3&gt;

&lt;p&gt;Congratulations, we played ourselves. All pods gone. CTFd completely down on k8s deployment and then all of PB started calling at the same time : &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%2Famodc6skghan01xvchee.jpeg" 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%2Famodc6skghan01xvchee.jpeg" alt=" " width="800" height="977"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Backup That Saved Us
&lt;/h2&gt;

&lt;p&gt;Here's where we owe a massive thank you to &lt;strong&gt;Ashutosh bhaiya&lt;/strong&gt; for his prescient advice: "Always keep a backup deployment ready."&lt;/p&gt;

&lt;p&gt;We had a secondary CTFd instance running on our PB server - completely separate from the Kubernetes cluster but connected to the same database. While Govind and I battled with the K8s deployment, this backup instance kept serving traffic to some participants.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Real Culprit
&lt;/h2&gt;

&lt;p&gt;After 30 minutes of debugging, checking migration scripts and nearly crying to claude for a fix, I saw one emergency pod created after some random claude commands finally healthy.&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%2Fg1munkv75ljhw2rbb7mp.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%2Fg1munkv75ljhw2rbb7mp.png" alt=" " width="320" height="180"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After everything settled down and we sat down for the RCA, we found out the real issue.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"We were using two different versions of CTFd from two different servers"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lavi's deployment : On PB Server&lt;/strong&gt;: Latest CTFd version&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Govind's deployment : On GCP K8S&lt;/strong&gt;: CTFd 3.7.2&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both connecting to the same database. Both trying to run different migration schemas. Both convinced they were right.&lt;/p&gt;

&lt;p&gt;And in honour of this moment, This meme was born : &lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1951981237419258332-512" src="https://platform.twitter.com/embed/Tweet.html?id=1951981237419258332"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1951981237419258332-512');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1951981237419258332&amp;amp;theme=dark"
  }



&lt;/p&gt;




&lt;h2&gt;
  
  
  What We Should Have Done
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Proper Load Balancing Architecture
&lt;/h3&gt;

&lt;p&gt;Instead of our ad-hoc "some users go here, some go there" approach, we should have implemented:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Ideal setup with external load balancer&lt;/span&gt;
&lt;span class="s"&gt;External DNS (Cloudflare/Route53)&lt;/span&gt;
         &lt;span class="s"&gt;|&lt;/span&gt;
    &lt;span class="s"&gt;Load Balancer&lt;/span&gt;
    &lt;span class="s"&gt;/           \&lt;/span&gt;
&lt;span class="s"&gt;K8s Cluster    PB Server&lt;/span&gt;
    &lt;span class="s"&gt;\           /&lt;/span&gt;
   &lt;span class="s"&gt;Shared Database&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This would have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatically distributed traffic between both deployments&lt;/li&gt;
&lt;li&gt;Provided seamless failover when K8s went down&lt;/li&gt;
&lt;li&gt;Prevented the full outage scenario&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Test Your Autoscaling (Or Don't Use It)
&lt;/h3&gt;

&lt;p&gt;Let's be honest - we enabled autoscaling because it sounded cool. Did we need it? Probably not. Did we test it? Definitely not. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lessons learned:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Autoscaling is not a silver bullet&lt;/li&gt;
&lt;li&gt;Test scaling behaviors in staging first&lt;/li&gt;
&lt;li&gt;Sometimes, vertical scaling &amp;gt; horizontal scaling for stateful apps&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Post-Mortem Action Items
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Apologise to Cyber Team&lt;/li&gt;
&lt;li&gt;[ ] Gaslight the participants that it wasn't a server issue, it was their internet that was flaky&lt;/li&gt;
&lt;li&gt;[ ] Remind myself to always use the latest version everywhere&lt;/li&gt;
&lt;li&gt;[ ] Beat up Govind for not telling me about the custom migration script he ran last night secretly until the autoscale pods crashed.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Past the memes
&lt;/h2&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%2Fhqekmx9pm1bcdd6rakdp.jpg" 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%2Fhqekmx9pm1bcdd6rakdp.jpg" alt=" " width="800" height="781"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PBCTF 4.0 taught us that running a CTF competition is as much about infrastructure resilience as it is about challenge quality. While our participants experienced 35 minutes of downtime, I think it was their internet at fault afterall.&lt;/p&gt;

&lt;p&gt;To all future CTF organizers: Learn from our mistakes. Pin your versions. Test your scaling. And maybe, just maybe, don't autoscale unless you really need to.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>kubernetes</category>
      <category>programming</category>
      <category>cybersecurity</category>
    </item>
    <item>
      <title>Kubernetes on the cloud vs on bare metal : Deception 101</title>
      <dc:creator>Akash Singh</dc:creator>
      <pubDate>Thu, 18 Sep 2025 07:41:10 +0000</pubDate>
      <link>https://forem.com/skysingh04/kubernetes-on-the-cloud-vs-on-bare-metal-deception-101-25a7</link>
      <guid>https://forem.com/skysingh04/kubernetes-on-the-cloud-vs-on-bare-metal-deception-101-25a7</guid>
      <description>&lt;h2&gt;
  
  
  The Great LoadBalancer Debate of 2:13 AM
&lt;/h2&gt;

&lt;p&gt;It started innocently enough. My friend &lt;a href="https://x.com/govind_404" rel="noopener noreferrer"&gt;Govind&lt;/a&gt; and I were debugging our Kubernetes setup when he dropped this bombshell:&lt;/p&gt;

&lt;p&gt;"Bro, my LoadBalancer is provisioned by Digital Ocean. It's not a K8s LoadBalancer service."&lt;/p&gt;

&lt;p&gt;I stared at my screen. It was 2:13 AM. My brain was running on pure chai.&lt;/p&gt;

&lt;p&gt;"Are you sure about what you're saying?" I typed back. "Why do you have LoadBalancer + Ingress then? What does it LoadBalance to?"&lt;/p&gt;

&lt;p&gt;What followed was a 20-minute debate that would fundamentally change how I understood Kubernetes. We were both right. We were both wrong. And we were both about to discover that "Cloud Native" is the tech industry's greatest marketing scam.&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;# What Govind showed me&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl get svc &lt;span class="nt"&gt;-n&lt;/span&gt; ingress-nginx
NAME                      TYPE           CLUSTER-IP      EXTERNAL-IP
ingress-nginx-controller  LoadBalancer   10.109.16.98   152.42.156.235

&lt;span class="c"&gt;# My claim: "This is a K8s service"&lt;/span&gt;
&lt;span class="c"&gt;# His claim: "This is a Digital Ocean Load Balancer"&lt;/span&gt;
&lt;span class="c"&gt;# The truth: We were having different conversations&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The debate got so heated that at 2:20 AM, Govind literally said, "Ye debate settle karna padega. Coming to your house." &lt;/p&gt;

&lt;p&gt;At 2:21 AM. On a Sunday.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1959519918426067151-372" src="https://platform.twitter.com/embed/Tweet.html?id=1959519918426067151"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1959519918426067151-372');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1959519918426067151&amp;amp;theme=dark"
  }



&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%2Fsuk97rhn9acr9tpwu8ce.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%2Fsuk97rhn9acr9tpwu8ce.png" alt=" " width="184" height="148"&gt;&lt;/a&gt;&lt;/p&gt;




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

&lt;p&gt;I am Akash Singh, a final year engineering student and Open Source Contributor from Bangalore.&lt;br&gt;
Here is my &lt;a href="https://www.linkedin.com/in/skysingh04/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, &lt;a href="https://github.com/SkySingh04" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; and &lt;a href="https://x.com/SkySingh04" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&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%2F4eayocft44kkbwoqpc8z.JPG" 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%2F4eayocft44kkbwoqpc8z.JPG" alt="Sky Singh" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I go by the name SkySingh04 online.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  The Revelation That Changed Everything
&lt;/h2&gt;

&lt;p&gt;After our debate (which we settled by asking Claude at 2:30 AM like real engineers), I decided to test something. I spun up the exact same Kubernetes cluster on a bare metal server.&lt;/p&gt;

&lt;p&gt;Same YAML. Same configurations. Same everything.&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;# On Digital Ocean - Govind's setup&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; ingress-service.yaml
&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl get svc
NAME                      TYPE           EXTERNAL-IP
ingress-nginx-controller  LoadBalancer   152.42.156.235  ✅

&lt;span class="c"&gt;# On my bare metal server - The shocking truth&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; ingress-service.yaml  &lt;span class="c"&gt;# EXACT SAME YAML&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl get svc
NAME                      TYPE           EXTERNAL-IP
ingress-nginx-controller  LoadBalancer   &amp;lt;pending&amp;gt;  ❌
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One hour passed. Still &lt;code&gt;&amp;lt;pending&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That's when it hit me like a ton of YAML files: &lt;strong&gt;I was right.&lt;/strong&gt; The LoadBalancer &lt;em&gt;was&lt;/em&gt; a K8s service. But he was also right – it &lt;em&gt;was&lt;/em&gt; provisioning a Digital Ocean Load Balancer. &lt;/p&gt;

&lt;p&gt;The real mindfuck? On bare metal, it does... nothing. It just sits there. Pending. Forever.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;type: LoadBalancer&lt;/code&gt; doesn't create a load balancer. It just asks your cloud provider to create one. No cloud provider? No load balancer. Just eternal pending and sadness.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Architecture of Deception : Kubernetes on the cloud vs on bare metal
&lt;/h2&gt;

&lt;p&gt;Here's what nobody tells you about &lt;code&gt;type: LoadBalancer&lt;/code&gt; in Kubernetes: &lt;strong&gt;It doesn't create a load balancer&lt;/strong&gt;. It just asks someone else to create one for you.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my-service&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;LoadBalancer&lt;/span&gt;  &lt;span class="c1"&gt;# &amp;lt;- This is just a prayer to the cloud gods&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On AWS, this YAML whispers to the AWS Cloud Controller Manager, which calls the AWS API, which provisions an Elastic Load Balancer, which costs you $20/month, which... works.&lt;/p&gt;

&lt;p&gt;On bare metal, this YAML whispers into the void. Nobody's listening. Nobody's home.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Kubernetes Actually Works on Cloud
&lt;/h3&gt;

&lt;p&gt;When you deploy Kubernetes on AWS, GCP, or Azure, there's a hidden component doing all the heavy lifting: the Cloud Controller Manager. It's like having a rich uncle who secretly pays for everything while you pretend to be independent.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your YAML → K8s API → Cloud Controller Manager → AWS API → Real Infrastructure
                                ↑
                    This guy has your credit card
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every cloud resource you think Kubernetes is managing? It's not. It's just asking the cloud provider to do it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;LoadBalancer Service&lt;/strong&gt; → Creates AWS ELB/ALB/NLB&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PersistentVolume&lt;/strong&gt; → Creates EBS volumes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cluster Autoscaler&lt;/strong&gt; → Calls EC2 APIs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ingress&lt;/strong&gt; → Often creates another load balancer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your monthly AWS bill is basically a list of things Kubernetes couldn't do by itself lmao.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Kubernetes "Works" on Bare Metal
&lt;/h3&gt;

&lt;p&gt;On bare metal, that same YAML becomes a wish list with no Santa:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your YAML → K8s API → ??? → Nothing happens → &amp;lt;pending&amp;gt; → Sadness
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To make it work, you need to install the Kubernetes Extended Universe™:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MetalLB&lt;/strong&gt;: Pretends to be a cloud load balancer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Longhorn/OpenEBS&lt;/strong&gt;: Pretends to be cloud storage&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cluster API&lt;/strong&gt;: Pretends to be cloud compute&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cert-Manager&lt;/strong&gt;: Because clouds gave you free SSL&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;External-DNS&lt;/strong&gt;: Because clouds handled DNS&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Some IPAM solution&lt;/strong&gt;: Because clouds managed IPs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By the time you're done, you've basically rebuilt AWS in your data center, poorly.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Cost Comparison
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Cloud Kubernetes:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Time to Production: 10 minutes&lt;/span&gt;
&lt;span class="c1"&gt;# Monthly Cost: $500-2000&lt;/span&gt;
&lt;span class="c1"&gt;# Mental Health: Intact&lt;/span&gt;
&lt;span class="c1"&gt;# What You're Actually Paying For:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;EKS/GKE/AKS Control Plane&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$75/month&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Load Balancers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$20 each&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;NAT Gateways&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$45 each&lt;/span&gt;  
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Data Transfer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$0.09/GB (the silent killer)&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Persistent Volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$0.10/GB/month&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;The privilege of not thinking about any of this&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Bare Metal Kubernetes:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Time to Production: 3 days to 3 weeks&lt;/span&gt;
&lt;span class="c1"&gt;# Monthly Cost: $100-500 (hardware/colocation)&lt;/span&gt;
&lt;span class="c1"&gt;# Mental Health: What mental health?&lt;/span&gt;
&lt;span class="c1"&gt;# Hidden Costs Nobody Mentions:&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Your time&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;40-80 hours of setup&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;Ongoing maintenance&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;10-20 hours/month&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;That 3 AM phone call when the node dies&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;The contractor you'll hire&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$150/hour&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Replacing the keyboard you broke in rage&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Uncomfortable Solutions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Option 1: Embrace the Lock-in
&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;# The path of least resistance&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; application.yaml
&lt;span class="nv"&gt;$ &lt;/span&gt;aws eks update-kubeconfig &lt;span class="nt"&gt;--name&lt;/span&gt; my-cluster
&lt;span class="nv"&gt;$ &lt;/span&gt;kubectl get svc  &lt;span class="c"&gt;# Everything has IPs!&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="c"&gt;# Go home at 5 PM&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just use EKS/GKE/AKS and accept that you're paying the "I want to sleep at night" tax. For most companies, the $500-2000/month is cheaper than the engineering time you'd spend fighting bare metal.&lt;/p&gt;

&lt;h3&gt;
  
  
  Option 2: The Bare Metal Warrior Path
&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;# The path of pain&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="c"&gt;# Install Ubuntu&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="c"&gt;# Install Kubernetes&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="c"&gt;# Install MetalLB&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="c"&gt;# Configure IP pools&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="c"&gt;# Install Longhorn&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="c"&gt;# Debug networking for 6 hours&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="c"&gt;# Question life choices&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="c"&gt;# Finally get a LoadBalancer IP&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="c"&gt;# Realize you need to do this on 5 more nodes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This path makes sense if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You have dedicated ops people who enjoy suffering&lt;/li&gt;
&lt;li&gt;You're at a scale where cloud costs exceed engineer salaries&lt;/li&gt;
&lt;li&gt;You have compliance requirements that forbid cloud&lt;/li&gt;
&lt;li&gt;You're a masochist&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Option 3: The Reasonable Middle Ground
&lt;/h3&gt;

&lt;p&gt;Use k3s, k0s, or MicroK8s. These distributions come with batteries included:&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;# k3s: Actually reasonable&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;curl &lt;span class="nt"&gt;-sfL&lt;/span&gt; https://get.k3s.io | sh -
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="c"&gt;# Includes Traefik (LoadBalancer alternative)&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="c"&gt;# Includes local-path storage&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="c"&gt;# Actually works on bare metal&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or just admit defeat and use Docker Compose for anything under 10 services.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Plot Twist: When Cloud Kubernetes Actually Makes Sense
&lt;/h2&gt;

&lt;p&gt;Let me be clear: I'm not saying Kubernetes on cloud is bad. For many scenarios, it's the right choice:&lt;/p&gt;

&lt;h3&gt;
  
  
  When Cloud Wins:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You need to scale from 10 to 10,000 pods based on traffic&lt;/li&gt;
&lt;li&gt;You have a team of 5 managing infrastructure for 500 developers&lt;/li&gt;
&lt;li&gt;Your compliance requires "high availability" (good luck doing that on bare metal)&lt;/li&gt;
&lt;li&gt;You value your weekends&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When Bare Metal Wins:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You're running a consistent workload 24/7 (cloud is just renting at that point)&lt;/li&gt;
&lt;li&gt;You have very specific hardware requirements (GPUs, high-frequency trading)&lt;/li&gt;
&lt;li&gt;You're at Facebook/Google scale (they use bare metal internally)&lt;/li&gt;
&lt;li&gt;You're learning and want to understand everything&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  My Honest Recommendations
&lt;/h2&gt;

&lt;p&gt;After suffering through both approaches, here's my actual advice:&lt;/p&gt;

&lt;h3&gt;
  
  
  For Startups (&amp;lt; 10 services)
&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;# Skip Kubernetes entirely&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;docker-compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="c"&gt;# Use the saved money for product development&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="c"&gt;# Graduate to K8s when you actually need it&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  For Growing Companies (10-100 services)
&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;# Just pay for managed Kubernetes&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;eksctl create cluster &lt;span class="nt"&gt;--name&lt;/span&gt; my-cluster
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="c"&gt;# Focus on your product, not infrastructure&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="c"&gt;# The cloud bill is cheaper than hiring more ops people&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  For Large Enterprises (100+ services)
&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;# You can afford to do it right&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="c"&gt;# Hire a platform team&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="c"&gt;# Build on bare metal if it saves millions&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="c"&gt;# Or stay on cloud if velocity matters more&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  For Learning
&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;# Use kind or minikube locally&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;kind create cluster
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="c"&gt;# Learn the concepts without the pain&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="c"&gt;# Deploy to cloud when you need production&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion: Making Peace with Reality
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Special thanks to Govind for the 2 AM debate that inspired this post. Yes, we're still friends. No, we still don't agree on who won. And yes, Naresh is still paying for that Digital Ocean LoadBalancer.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;After all my rage against the cloud native machine, here's where I've landed:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use cloud Kubernetes if:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You value velocity over cost&lt;/li&gt;
&lt;li&gt;You have variable workloads&lt;/li&gt;
&lt;li&gt;You want to focus on your product&lt;/li&gt;
&lt;li&gt;You like sleeping&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use bare metal Kubernetes if:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You have consistent workloads&lt;/li&gt;
&lt;li&gt;You have a dedicated ops team&lt;/li&gt;
&lt;li&gt;You're at massive scale&lt;/li&gt;
&lt;li&gt;You enjoy pain (this is valid)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use something else if:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You have less than 10 services (seriously, just use Docker Compose)&lt;/li&gt;
&lt;li&gt;You don't need the complexity&lt;/li&gt;
&lt;li&gt;You're a solo developer&lt;/li&gt;
&lt;li&gt;You value simplicity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The truth is, "Cloud Native" isn't a lie – it's just poorly named. It should be called "Cloud Optimized" or "Cloud Enhanced" or, more honestly, "Only Really Works Properly On Cloud But We Can't Say That Because It Sounds Bad."&lt;/p&gt;

&lt;p&gt;And that's okay. Not everything needs to be portable. Not everything needs to run on your laptop. Sometimes, paying AWS to handle the complexity is the smartest business decision you can make.&lt;/p&gt;

&lt;p&gt;Just don't pretend it's portable. Don't pretend there's no lock-in. And definitely don't try to run LoadBalancer services on bare metal at 3 AM. Trust me on that last one.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>cloud</category>
      <category>aws</category>
      <category>programming</category>
    </item>
    <item>
      <title>Argo, Flux, Kustomize, Helm and all the fancy stuff about GitOps</title>
      <dc:creator>Akash Singh</dc:creator>
      <pubDate>Fri, 15 Aug 2025 13:09:04 +0000</pubDate>
      <link>https://forem.com/skysingh04/argo-flux-kustomize-helm-and-all-the-fancy-stuff-about-gitops-gkl</link>
      <guid>https://forem.com/skysingh04/argo-flux-kustomize-helm-and-all-the-fancy-stuff-about-gitops-gkl</guid>
      <description>&lt;p&gt;Every now and then, I open the CNCF Landscape and think: Would most non-engineers be able to differentiate if these are names of Software Engineering tools or Pokémon?&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1955321080958030160-880" src="https://platform.twitter.com/embed/Tweet.html?id=1955321080958030160"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1955321080958030160-880');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1955321080958030160&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;So when I casually mentioned "I'm doing GitOps now" in a team meeting, I was immediately bombarded with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Oh, are you using Argo?"
"ArgoCD or Argo Workflows?"
"Why not Flux?"
"Flux v1 or v2?"
"Are you using Helm?"
"Helm with Kustomize or just Helm?"
"What about Jsonnet?"
"Have you tried Kapitan?"
"Don't forget Argo Events!"
"And Argo Rollouts!"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I nodded along, pretending I knew what everyone was talking about, frantically taking notes that looked like:&lt;/p&gt;

&lt;p&gt;Argo (CD? Workflows? Events? Rollouts? Is this one tool or four???)&lt;br&gt;
Flux (there are versions???)&lt;br&gt;
Helm (⛵ boat emoji because lmao)&lt;br&gt;
Kustomize (customize but with K because...Kubernetes???)&lt;/p&gt;

&lt;p&gt;Three months and countless conversations, building and breaking later, I finally understand what all these tools actually DO. So I'm writing this blog to save you from the same confusion I went through. And yes Falco is straight up legendary Pokémon :D&lt;/p&gt;


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

&lt;p&gt;I am Akash Singh, a final year engineering student and Open Source Contributor from Bangalore.&lt;br&gt;
Here is my &lt;a href="https://www.linkedin.com/in/skysingh04/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, &lt;a href="https://github.com/SkySingh04" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; and &lt;a href="https://x.com/SkySingh04" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&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%2F4eayocft44kkbwoqpc8z.JPG" 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%2F4eayocft44kkbwoqpc8z.JPG" alt="Sky Singh" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I go by the name SkySingh04 online.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  What Even Is GitOps?
&lt;/h2&gt;

&lt;p&gt;Before we dive into all these tools, let's get one thing straight: GitOps is just a fancy way of saying "Git is the boss of your infrastructure." &lt;/p&gt;

&lt;p&gt;Instead of SSHing into servers or running kubectl commands from your laptop, everything goes through Git:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Want to deploy? Push to Git.&lt;/li&gt;
&lt;li&gt;Want to rollback? Revert the Git commit.&lt;/li&gt;
&lt;li&gt;Want to know what's running in production? Look at Git.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The magic happens through &lt;strong&gt;pull-based deployment&lt;/strong&gt;: Instead of your CI/CD pushing changes TO your cluster, your cluster pulls changes FROM Git. (This also means your CI/CD never needs production credentials hehe)&lt;/p&gt;

&lt;p&gt;Now let me introduce slowly all the fancy keywords being thrown around here.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Configuration Tools: How to Structure Your Kubernetes YAML
&lt;/h2&gt;

&lt;p&gt;Before you can do GitOps, you need to organize your Kubernetes configurations.&lt;/p&gt;
&lt;h3&gt;
  
  
  Plain YAML: The Starting Point
&lt;/h3&gt;

&lt;p&gt;This is just raw Kubernetes manifests. Cute YAML files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my-app&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx:1.14.2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What they do&lt;/strong&gt;: Nothing (Just like my DNS server that I wrote in rust T-T)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The problem they creates&lt;/strong&gt;: You end up copying these files for each environment (dev, staging, prod) and manually editing values. Lots of circus.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How it ties to GitOps&lt;/strong&gt;: These YAML files live in Git, and GitOps tools apply them to your cluster.&lt;/p&gt;

&lt;h3&gt;
  
  
  Helm: The Package Manager
&lt;/h3&gt;

&lt;p&gt;Helm treats Kubernetes applications like packages. My javascript bros found their npm for Kubernetes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Template&lt;/span&gt;
&lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{{&lt;/span&gt; &lt;span class="nv"&gt;.Values.replicas&lt;/span&gt; &lt;span class="pi"&gt;}}&lt;/span&gt;

&lt;span class="c1"&gt;# Values file&lt;/span&gt;
&lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What it does&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Templates your YAML using Go templates&lt;/li&gt;
&lt;li&gt;Packages applications into "charts"&lt;/li&gt;
&lt;li&gt;Manages releases (install, upgrade, rollback)&lt;/li&gt;
&lt;li&gt;Handles dependencies between apps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How it ties to GitOps&lt;/strong&gt;: Your Helm charts and values files live in Git. GitOps tools like ArgoCD/Flux can render and deploy Helm charts directly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Kustomize: The Patcher
&lt;/h3&gt;

&lt;p&gt;Kustomize says "don't template, just patch." Start with plain YAML and overlay changes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Base YAML stays plain&lt;/span&gt;
&lt;span class="c1"&gt;# Then you add patches for each environment&lt;/span&gt;
&lt;span class="na"&gt;patches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;my-app&lt;/span&gt;
    &lt;span class="na"&gt;patch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|-&lt;/span&gt;
      &lt;span class="s"&gt;- op: replace&lt;/span&gt;
        &lt;span class="s"&gt;path: /spec/replicas&lt;/span&gt;
        &lt;span class="s"&gt;value: 5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What it does&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Takes base YAML files and applies patches/overlays&lt;/li&gt;
&lt;li&gt;No templating language, All is YAML&lt;/li&gt;
&lt;li&gt;Built into kubectl (&lt;code&gt;kubectl apply -k&lt;/code&gt;) (this is the selling point fr)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How it ties to GitOps&lt;/strong&gt;: Your base configs and overlays live in Git. GitOps tools natively understand Kustomize directories.&lt;/p&gt;

&lt;h3&gt;
  
  
  FAST FAST REVISION
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Plain YAML&lt;/strong&gt;: No tooling, lots of duplication&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Helm&lt;/strong&gt;: Powerful templating + package management, but another language to learn&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kustomize&lt;/strong&gt;: Stay close to vanilla YAML, just patch what's different&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The GitOps Engines: The Deployment Orchestrators
&lt;/h2&gt;

&lt;p&gt;These tools watch your Git repos and make sure your cluster matches what's in Git.&lt;/p&gt;

&lt;h3&gt;
  
  
  ArgoCD: The GitOps Powerhouse
&lt;/h3&gt;

&lt;p&gt;ArgoCD is probably what most people think of when they hear "GitOps."&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1949927509971390487-134" src="https://platform.twitter.com/embed/Tweet.html?id=1949927509971390487"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1949927509971390487-134');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1949927509971390487&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it does&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Watches your Git repositories&lt;/li&gt;
&lt;li&gt;Compares desired state (Git) with actual state (cluster)&lt;/li&gt;
&lt;li&gt;Syncs changes automatically or manually&lt;/li&gt;
&lt;li&gt;Provides a web UI to visualize everything&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What makes it different&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The UI&lt;/strong&gt;: Beautiful web interface showing your entire application topology&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-cluster support&lt;/strong&gt;: Manage multiple clusters from one ArgoCD instance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sync waves and hooks&lt;/strong&gt;: Complex deployment orchestration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built-in RBAC&lt;/strong&gt;: Enterprise-ready from day one&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How it works with config tools&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatically detects if you're using Helm, Kustomize, or plain YAML&lt;/li&gt;
&lt;li&gt;Can pass values to Helm or parameters to Kustomize&lt;/li&gt;
&lt;li&gt;Supports custom plugins for other tools&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Flux: The Cloud Native GitOps
&lt;/h3&gt;

&lt;p&gt;Flux takes a more modular, Kubernetes-native approach.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it does&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Same core idea: syncs Git with your cluster&lt;/li&gt;
&lt;li&gt;But built as a set of small, focused controllers&lt;/li&gt;
&lt;li&gt;No UI - everything is a Kubernetes resource&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What makes it different&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Architecture&lt;/strong&gt;: Not a monolithic app but a collection of controllers:

&lt;ul&gt;
&lt;li&gt;Source Controller (fetches from Git)&lt;/li&gt;
&lt;li&gt;Kustomize Controller (builds and applies)&lt;/li&gt;
&lt;li&gt;Helm Controller (manages Helm releases)&lt;/li&gt;
&lt;li&gt;Notification Controller (alerts and webhooks)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Multi-tenancy first&lt;/strong&gt;: Designed for platform teams serving multiple dev teams&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Lighter footprint&lt;/strong&gt;: Uses fewer resources than ArgoCD&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;GitOps for GitOps&lt;/strong&gt;: Flux can manage itself&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How it works with config tools&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Native Kustomize support through Kustomize Controller&lt;/li&gt;
&lt;li&gt;Native Helm support through Helm Controller&lt;/li&gt;
&lt;li&gt;Can even fetch Helm charts from OCI registries&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  ArgoCD vs Flux:
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;ArgoCD&lt;/th&gt;
&lt;th&gt;Flux&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;UI&lt;/td&gt;
&lt;td&gt;Beautiful web UI&lt;/td&gt;
&lt;td&gt;No UI (but you can add one)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Architecture&lt;/td&gt;
&lt;td&gt;Monolithic application&lt;/td&gt;
&lt;td&gt;Set of controllers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Resource usage&lt;/td&gt;
&lt;td&gt;Heavier&lt;/td&gt;
&lt;td&gt;Lighter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Learning curve&lt;/td&gt;
&lt;td&gt;Easier (thanks to UI)&lt;/td&gt;
&lt;td&gt;Steeper (all CLI/YAML)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-tenancy&lt;/td&gt;
&lt;td&gt;Supported&lt;/td&gt;
&lt;td&gt;First-class citizen&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-management&lt;/td&gt;
&lt;td&gt;Can manage itself&lt;/td&gt;
&lt;td&gt;Designed to manage itself&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Community&lt;/td&gt;
&lt;td&gt;Larger, more tutorials&lt;/td&gt;
&lt;td&gt;Smaller but growing&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Choose ArgoCD if&lt;/strong&gt;: You want a UI, easier onboarding, enterprise features out of the box&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Choose Flux if&lt;/strong&gt;: You prefer everything as code, need strong multi-tenancy, building a platform&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1945459214434144285-798" src="https://platform.twitter.com/embed/Tweet.html?id=1945459214434144285"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1945459214434144285-798');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1945459214434144285&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;h2&gt;
  
  
  The Argo Ecosystem: Where the confusion happens
&lt;/h2&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%2Fkzjvmclyhgf7iy04oj7t.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%2Fkzjvmclyhgf7iy04oj7t.png" alt=" " width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As it turns out, ArgoCD is actually part of a larger family. And as far as I have seen on the internet, People pick some members of this family to work with flux.&lt;/p&gt;

&lt;h3&gt;
  
  
  Argo Workflows: The Pipeline Runner
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it does&lt;/strong&gt;: Runs complex, multi-step workflows on Kubernetes&lt;/p&gt;

&lt;p&gt;Think of it as Jenkins or GitHub Actions, but Kubernetes-native. Each step in your workflow runs as a container.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What makes it different&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Workflows are Kubernetes resources (YAML)&lt;/li&gt;
&lt;li&gt;DAG-based (define dependencies between steps)&lt;/li&gt;
&lt;li&gt;Massive parallelization capabilities&lt;/li&gt;
&lt;li&gt;Native Kubernetes integration (uses pods, volumes, configs)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Common use cases&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CI/CD pipelines&lt;/li&gt;
&lt;li&gt;Data processing pipelines&lt;/li&gt;
&lt;li&gt;Machine learning workflows&lt;/li&gt;
&lt;li&gt;Batch jobs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How it ties to GitOps&lt;/strong&gt;: Often triggered by Argo Events to build and push images, which then triggers ArgoCD to deploy them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Argo Events: The Event Handler
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it does&lt;/strong&gt;: Listens for events and triggers actions in Kubernetes&lt;/p&gt;

&lt;p&gt;It's like IFTTT or Zapier for Kubernetes: "When this happens, do that."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What makes it different&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Huge variety of event sources:

&lt;ul&gt;
&lt;li&gt;Webhooks (GitHub, GitLab, Slack)&lt;/li&gt;
&lt;li&gt;Message queues (Kafka, NATS, SQS)&lt;/li&gt;
&lt;li&gt;Time-based (cron, calendar)&lt;/li&gt;
&lt;li&gt;Cloud events (S3 uploads, pub/sub)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Can trigger any Kubernetes resource (including Argo Workflows)&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Common use cases&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Trigger builds on Git push&lt;/li&gt;
&lt;li&gt;Process files when uploaded to S3&lt;/li&gt;
&lt;li&gt;Run nightly batch jobs&lt;/li&gt;
&lt;li&gt;Incident response automation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How it ties to GitOps&lt;/strong&gt;: Provides the event-driven glue between your source code changes and your GitOps deployments.&lt;/p&gt;

&lt;h3&gt;
  
  
  Argo Rollouts: The Progressive Delivery Tool
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What it does&lt;/strong&gt;: Advanced deployment strategies (canary, blue-green, experiments)&lt;/p&gt;

&lt;p&gt;While ArgoCD gets your app deployed, Rollouts controls HOW it gets deployed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What makes it different&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gradual rollouts with automatic rollback&lt;/li&gt;
&lt;li&gt;Integration with metrics providers (Prometheus, Datadog)&lt;/li&gt;
&lt;li&gt;Traffic management with service meshes&lt;/li&gt;
&lt;li&gt;A/B testing and experimentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How it ties to GitOps&lt;/strong&gt;: Works alongside ArgoCD/Flux to provide safe, gradual deployments.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It All Fits Together
&lt;/h2&gt;

&lt;p&gt;Here's how these tools work together in a real GitOps pipeline:&lt;/p&gt;

&lt;h3&gt;
  
  
  The Complete Flow
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Developer pushes code to GitHub
2. Argo Events detects the push
3. Argo Events triggers Argo Workflows
4. Argo Workflows:
   - Builds the application
   - Runs tests
   - Builds and pushes Docker image
   - Updates image tag in the config repo
5. ArgoCD/Flux detects the config change
6. ArgoCD/Flux applies the changes to Kubernetes
7. Optionally: Argo Rollouts performs canary deployment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Repository Structure in GitOps
&lt;/h3&gt;

&lt;p&gt;You typically have two repos:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Application Repository&lt;/strong&gt; : Owned by Developers&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my-app/
├── src/
├── Dockerfile
└── .github/workflows/  # or Argo Workflows
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Configuration Repository&lt;/strong&gt; : Owned by the cool kids (Devops Team)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;k8s-configs/
├── apps/
│   └── my-app/
│       ├── base/           # Kustomize base
│       │   └── deployment.yaml
│       ├── overlays/       # Kustomize overlays
│       │   ├── dev/
│       │   └── prod/
│       └── charts/         # Or Helm charts
└── argocd/                 # ArgoCD applications
    └── apps/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Tool Combinations in the Wild
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Common Pattern 1: The Argo Stack&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ArgoCD for GitOps&lt;/li&gt;
&lt;li&gt;Argo Workflows for CI/CD&lt;/li&gt;
&lt;li&gt;Argo Events for automation&lt;/li&gt;
&lt;li&gt;Kustomize for configuration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Common Pattern 2: The Flux Stack&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Flux for GitOps&lt;/li&gt;
&lt;li&gt;GitHub Actions/GitLab CI for CI/CD&lt;/li&gt;
&lt;li&gt;Helm for third-party apps&lt;/li&gt;
&lt;li&gt;Kustomize for internal apps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Common Pattern 3: The Hybrid&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Flux for platform/infrastructure (used by platform team)&lt;/li&gt;
&lt;li&gt;ArgoCD for applications (used by dev teams - they get a UI!)&lt;/li&gt;
&lt;li&gt;Helm for third-party apps&lt;/li&gt;
&lt;li&gt;Kustomize for customization&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  So Which Pokemon do I choose?
&lt;/h2&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%2Fkiousiqj06gowqqgcfxz.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%2Fkiousiqj06gowqqgcfxz.png" alt=" " width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;You don't need all these tools.&lt;/strong&gt; Start with ArgoCD/Flux + Kustomize. That's enough for 80% of use cases.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The tools are the easy part.&lt;/strong&gt; The hard part is changing your team's workflows and getting everyone to stop running kubectl manually.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Secret management is still painful.&lt;/strong&gt; You'll need something like Sealed Secrets, SOPS, or External Secrets Operator.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Image tag updates are annoying.&lt;/strong&gt; Every new build means a commit to your config repo. (Both Flux and ArgoCD have solutions for this.)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Don't try to build the perfect GitOps platform on day one. You will shoot yourself in the foot.&lt;/p&gt;

&lt;p&gt;But if you are like me and still want to break things just for the sake of it : &lt;br&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%2F7tr8techq53et0has8un.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%2F7tr8techq53et0has8un.png" alt=" " width="500" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The TL;DR of the mess
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitOps&lt;/strong&gt;: Git is your source of truth, clusters pull from Git&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Helm vs Kustomize&lt;/strong&gt;: Helm for packages and templating, Kustomize for patching&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ArgoCD vs Flux&lt;/strong&gt;: ArgoCD for nice UI and easy start, Flux for platform building&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Argo Family&lt;/strong&gt;: Workflows for pipelines, Events for automation, Rollouts for progressive delivery&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remember: These tools exist to solve problems. If you don't have the problem, you don't need the tool. Start with your pain points and add tools as needed. As engineers, it is our no. 1 goal to solve actual problems instead of creating 20 new problems with an over-engineered tech-stack.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>cncf</category>
      <category>beginners</category>
      <category>cloud</category>
    </item>
    <item>
      <title>DreamOps: The AI Agent That Fixes the Oncall Circus</title>
      <dc:creator>Akash Singh</dc:creator>
      <pubDate>Wed, 25 Jun 2025 13:49:42 +0000</pubDate>
      <link>https://forem.com/skysingh04/dreamops-the-ai-agent-thats-fixes-the-oncall-circus-2apl</link>
      <guid>https://forem.com/skysingh04/dreamops-the-ai-agent-thats-fixes-the-oncall-circus-2apl</guid>
      <description>&lt;h2&gt;
  
  
  The Circus of Being Oncall
&lt;/h2&gt;

&lt;p&gt;Picture this: It's 3 AM. Your phone buzzes with that dreaded PagerDuty alert. Your production database is down, users are angry, and you're stumbling in the dark trying to diagnose what went wrong. Sound familiar?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This is the reality for thousands of on-call engineers worldwide:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Constant sleep interruptions and alert fatigue&lt;/li&gt;
&lt;li&gt;Manual log analysis across multiple systems under pressure
&lt;/li&gt;
&lt;li&gt;30-60 minutes of stressful debugging for common issues&lt;/li&gt;
&lt;li&gt;Inconsistent remediation quality when you're exhausted&lt;/li&gt;
&lt;li&gt;Burnout from repetitive tasks that could be automated&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We built &lt;strong&gt;DreamOps&lt;/strong&gt; to solve this exact problem. And the results? &lt;strong&gt;Mind-blowing.&lt;/strong&gt;&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%2Fztjcouke790qu4saihmn.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%2Fztjcouke790qu4saihmn.png" alt=" " width="800" height="579"&gt;&lt;/a&gt;&lt;/p&gt;




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

&lt;p&gt;I am Akash Singh, a third year engineering student and Open Source Contributor from Bangalore.&lt;br&gt;
Here is my &lt;a href="https://www.linkedin.com/in/skysingh04/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, &lt;a href="https://github.com/SkySingh04" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; and &lt;a href="https://x.com/SkySingh04" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&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%2F4eayocft44kkbwoqpc8z.JPG" 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%2F4eayocft44kkbwoqpc8z.JPG" alt="Sky Singh" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I go by the name SkySingh04 online.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  Meet DreamOps: Your AI-Powered On-Call Partner
&lt;/h2&gt;

&lt;p&gt;DreamOps is an intelligent incident response platform that automatically triages and resolves infrastructure issues using Claude AI and advanced integrations. Think of it as having a senior DevOps engineer who never sleeps, never gets tired, and learns from every incident.&lt;/p&gt;
&lt;h3&gt;
  
  
  🎯 &lt;strong&gt;The Impact&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;80% faster incident resolution&lt;/strong&gt; (2-5 minutes vs 30-60 minutes)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2-4 hours saved per on-call shift&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero 3 AM wake-up calls&lt;/strong&gt; for routine issues&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistent remediation quality&lt;/strong&gt; regardless of time of day&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1936766682464428497-731" src="https://platform.twitter.com/embed/Tweet.html?id=1936766682464428497"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1936766682464428497-731');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1936766682464428497&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;h3&gt;
  
  
  🔧 &lt;strong&gt;How It Works&lt;/strong&gt;
&lt;/h3&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%2Fonc06s0zv79qz6vnn3l7.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%2Fonc06s0zv79qz6vnn3l7.png" alt=" " width="800" height="431"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When PagerDuty sends an alert, our AI agent:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Instantly analyzes&lt;/strong&gt; the incident with full Kubernetes context&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Diagnoses root cause&lt;/strong&gt; using logs, metrics, and documentation
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Executes remediation&lt;/strong&gt; commands automatically (with safety checks)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Only escalates&lt;/strong&gt; truly complex issues that need human intervention&lt;/li&gt;
&lt;/ol&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%2Fxc4i4c1a3dbv3tod2myt.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%2Fxc4i4c1a3dbv3tod2myt.png" alt=" " width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Tech Behind the Magic ✨
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;AI-First Architecture&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Claude AI Integration&lt;/strong&gt;: Advanced reasoning for root cause analysis&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model Context Protocol (MCP)&lt;/strong&gt;: Seamless integration with 10+ tools&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confidence Scoring&lt;/strong&gt;: Only auto-executes actions with ≥80% confidence&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Risk Assessment&lt;/strong&gt;: Categorizes commands as low/medium/high risk&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Production-Ready Stack&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Backend&lt;/strong&gt;: Python FastAPI with async processing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frontend&lt;/strong&gt;: Next.js SaaS interface with real-time dashboards&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure&lt;/strong&gt;: AWS ECS/EKS deployment ready&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integrations&lt;/strong&gt;: Kubernetes, PagerDuty, Grafana, GitHub, Slack, Notion&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;YOLO Mode&lt;/strong&gt; 🎢
&lt;/h3&gt;

&lt;p&gt;Yes, we actually called it YOLO mode. When enabled, DreamOps autonomously executes remediation commands for common issues like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pod crashes (CrashLoopBackOff)&lt;/li&gt;
&lt;li&gt;Memory issues (OOMKilled)
&lt;/li&gt;
&lt;li&gt;Configuration problems&lt;/li&gt;
&lt;li&gt;Deployment failures&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;But don't worry - it's safer than it sounds. Every action is risk-assessed and confidence-scored.&lt;/em&gt;&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%2Fpvpoil1i7svh96k6f2uo.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%2Fpvpoil1i7svh96k6f2uo.png" alt=" " width="800" height="355"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  From Hackathon Glory to Production Reality
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Lightspeed Warpseed 2025 Victory&lt;/strong&gt; 🏆
&lt;/h3&gt;

&lt;p&gt;This project didn't just emerge from our shared frustration with traditional incident response - it was born in the crucible of competition. At the &lt;strong&gt;Lightspeed Warpseed 2025 hackathon&lt;/strong&gt;, we took our 3 AM debugging nightmares and turned them into a winning solution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The result? We won $3,000 USD and validation that we'd struck gold.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;The hackathon judges were blown away by our approach to solving a problem that every engineer in the room had experienced. While other teams built incremental improvements, we reimagined incident response from the ground up with AI at the core.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;The Hackathon Journey&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;We've all been there - debugging production issues at ungodly hours, making critical decisions while sleep-deprived. During the hackathon, we:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Identified the core pain point&lt;/strong&gt; that affects millions of engineers worldwide&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Leveraged cutting-edge AI&lt;/strong&gt; (Claude) in ways no one had attempted before&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built a working prototype&lt;/strong&gt; that actually resolved real Kubernetes issues&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Demonstrated measurable impact&lt;/strong&gt; with our 80% faster resolution times&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The hackathon victory wasn't just about the prize money - it was proof that the developer community desperately needed this solution.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/na-pxlHH4YE"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;From Prototype to Platform&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;What started as a 48-hour hackathon sprint has evolved into a comprehensive platform that's changing how teams handle incidents. The $3,000 prize was just the beginning - we've since invested every dollar back into making DreamOps production-ready.&lt;/p&gt;

&lt;p&gt;🔗 &lt;strong&gt;Check out our journey:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/SkySingh04/DreamOps" rel="noopener noreferrer"&gt;Project Repository&lt;/a&gt; &lt;em&gt;(Currently private - building in stealth mode)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.google.com/presentation/d/1He5Ncvms5sOkStNiyVPttFkGBc3-AcBxB80Mj5xuPMg/edit?slide=id.p1#slide=id.p1" rel="noopener noreferrer"&gt;Pitch Presentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://drive.google.com/file/d/1Wi18x748xkNHCe25qYMs4ejcrQWcJuOz/view" rel="noopener noreferrer"&gt;Demo Video&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://devfolio.co/projects/dreamops-9f20" rel="noopener noreferrer"&gt;Devfolio Project&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1937087277215416359-404" src="https://platform.twitter.com/embed/Tweet.html?id=1937087277215416359"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1937087277215416359-404');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1937087277215416359&amp;amp;theme=dark"
  }



&lt;/p&gt;




&lt;h2&gt;
  
  
  Real-World Results That Speak Volumes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Before DreamOps:&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;45-minute average incident resolution time&lt;/li&gt;
&lt;li&gt;Engineers woken up 3-5 times per night&lt;/li&gt;
&lt;li&gt;Inconsistent fixes due to human error under pressure&lt;/li&gt;
&lt;li&gt;High on-call stress and burnout rates&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;After DreamOps:&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;5-minute average resolution for common issues
&lt;/li&gt;
&lt;li&gt;90% reduction in middle-of-night escalations&lt;/li&gt;
&lt;li&gt;Standardized, tested remediation procedures&lt;/li&gt;
&lt;li&gt;Engineers actually getting sleep 😴&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"DreamOps doesn't just solve incidents faster - it learns from each one to prevent future occurrences. It's like having a senior engineer who gets smarter with every alert."&lt;/em&gt; - The Team&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  What's Next: Building the Future of Incident Response
&lt;/h2&gt;

&lt;p&gt;We're not stopping here. The hackathon victory was just the beginning - DreamOps is evolving into the definitive platform for intelligent infrastructure management.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Post-Hackathon Roadmap:&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🔮 &lt;strong&gt;Predictive Incident Prevention&lt;/strong&gt;: Stop issues before they happen&lt;/li&gt;
&lt;li&gt;🌐 &lt;strong&gt;Multi-Cloud Support&lt;/strong&gt;: AWS, GCP, Azure integration
&lt;/li&gt;
&lt;li&gt;📊 &lt;strong&gt;Advanced Analytics&lt;/strong&gt;: Cost impact analysis and SLO tracking&lt;/li&gt;
&lt;li&gt;🤝 &lt;strong&gt;Team Collaboration&lt;/strong&gt;: Intelligent escalation and knowledge sharing&lt;/li&gt;
&lt;li&gt;🛡️ &lt;strong&gt;Security Integration&lt;/strong&gt;: Automated security incident response&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Looking for Strategic Partners &amp;amp; Investors&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Our hackathon victory proved market demand - now we're scaling.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We're actively seeking investors and strategic partners who understand the massive pain point we're solving. The incident response market is ripe for disruption, and early adopters are seeing transformational results.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why invest in DreamOps?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🏆 &lt;strong&gt;Proven concept&lt;/strong&gt;: $3,000 hackathon winner with judge validation&lt;/li&gt;
&lt;li&gt;📈 &lt;strong&gt;Massive market&lt;/strong&gt;: $2B+ incident management market growing 15% annually&lt;/li&gt;
&lt;li&gt;🎯 &lt;strong&gt;Demonstrated traction&lt;/strong&gt;: Real results from early adopters&lt;/li&gt;
&lt;li&gt;🚀 &lt;strong&gt;AI-first approach&lt;/strong&gt;: Leveraging the latest advances in LLMs&lt;/li&gt;
&lt;li&gt;👥 &lt;strong&gt;Experienced team&lt;/strong&gt;: Deep DevOps and AI expertise&lt;/li&gt;
&lt;li&gt;🔧 &lt;strong&gt;Production-ready&lt;/strong&gt;: Not just a prototype - full enterprise platform&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Experience DreamOps Today
&lt;/h2&gt;

&lt;p&gt;Ready to revolutionize your incident response? Here's how to get started:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;For Teams:&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Quick Setup&lt;/strong&gt;: Deploy in under 30 minutes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pilot Program&lt;/strong&gt;: Start with non-critical alerts
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gradual Rollout&lt;/strong&gt;: Expand to full production workloads&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sleep Better&lt;/strong&gt;: Enjoy uninterrupted nights&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;For Investors:&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Schedule a demo call with our team&lt;/li&gt;
&lt;li&gt;Review our pitch deck and financials
&lt;/li&gt;
&lt;li&gt;Meet our early adopters and hear their stories&lt;/li&gt;
&lt;li&gt;Join us in transforming how the world handles incidents&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Team Behind the Magic
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.linkedin.com/in/skysingh04/" rel="noopener noreferrer"&gt;Sky Singh&lt;/a&gt;&lt;/strong&gt; - Lead Developer&lt;br&gt;&lt;br&gt;
&lt;strong&gt;&lt;a href="https://www.linkedin.com/in/inchara-j-752050251/" rel="noopener noreferrer"&gt;Inchara J&lt;/a&gt;&lt;/strong&gt; - AI/ML Engineer&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Himanshu&lt;/strong&gt; - Frontend Developer&lt;br&gt;&lt;br&gt;
&lt;strong&gt;&lt;a href="https://www.linkedin.com/in/harshkg23/" rel="noopener noreferrer"&gt;Harsh Kumar Gupta&lt;/a&gt;&lt;/strong&gt; - Backend Systems&lt;br&gt;&lt;br&gt;
&lt;strong&gt;&lt;a href="https://www.linkedin.com/in/shubhangsinha/" rel="noopener noreferrer"&gt;Shubhang Sinha&lt;/a&gt;&lt;/strong&gt; - Cancelled on us&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A diverse team united by a shared mission: making on-call duty humane again. Our hackathon victory proved we have the skills - now we're building the future.&lt;/em&gt;&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%2Frkyx3eikp23i9ffdmfd3.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%2Frkyx3eikp23i9ffdmfd3.png" alt=" " width="680" height="680"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Get Involved
&lt;/h2&gt;

&lt;p&gt;Whether you're an engineer tired of 3 AM alerts, a CTO looking to improve team productivity, or an investor seeking the next big DevOps breakthrough - we want to connect.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;From hackathon winners to your production environment - let's build the future of incident response together.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📧 Contact us&lt;/strong&gt;: [Insert contact information]&lt;br&gt;&lt;br&gt;
&lt;strong&gt;🐦 Follow our journey&lt;/strong&gt;: &lt;a href="https://x.com/SkySingh04" rel="noopener noreferrer"&gt;@SkySingh04&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;💼 Investment inquiries&lt;/strong&gt;: [Insert investor contact]&lt;br&gt;&lt;br&gt;
&lt;strong&gt;🔧 Early access&lt;/strong&gt;: [Insert beta signup link]&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;The future of incident response is here. It's intelligent, it's automated, and it lets you sleep through the night.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ready to dream easy while AI takes care of your on-call duty?&lt;/em&gt;&lt;/p&gt;



&lt;p&gt;&lt;em&gt;DreamOps - Because 3 AM debugging sessions should be a thing of the past.&lt;/em&gt; ✨&lt;/p&gt;

&lt;p&gt;&lt;em&gt;P.S. - We're still celebrating our Lightspeed Warpseed 2025 victory, but we're more excited about the problems we're solving for engineers worldwide. Join us on this journey!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1936766175125631017-649" src="https://platform.twitter.com/embed/Tweet.html?id=1936766175125631017"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1936766175125631017-649');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1936766175125631017&amp;amp;theme=dark"
  }



&lt;/p&gt;

</description>
      <category>ai</category>
      <category>devops</category>
      <category>programming</category>
      <category>python</category>
    </item>
    <item>
      <title>The Art Of Chaos Engineering : LFX 2025 Experience</title>
      <dc:creator>Akash Singh</dc:creator>
      <pubDate>Sun, 01 Jun 2025 11:27:09 +0000</pubDate>
      <link>https://forem.com/skysingh04/the-art-of-chaos-engineering-lfx-2025-experience-4o2m</link>
      <guid>https://forem.com/skysingh04/the-art-of-chaos-engineering-lfx-2025-experience-4o2m</guid>
      <description>&lt;p&gt;I was selected for the LFX Mentorship Program 2025 under LitmusChaos where my project was &lt;a href="https://mentorship.lfx.linuxfoundation.org/project/445a6158-3ba7-429e-b0e1-f7417ff9a724" rel="noopener noreferrer"&gt;CNCF - LitmusChaos: CI/CD Integration, SDK Development &amp;amp; Chaos-CI-Lib Revamp&lt;/a&gt;&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%2Fzk3k5fnyuswtvh4xylnp.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%2Fzk3k5fnyuswtvh4xylnp.png" alt=" " width="800" height="368"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;During my mentorship, I submitted a total of 7 PR's to 4 repositories of LitmusChaos with approximately 14k lines of code. A detailed gist containing all of my contribution PR's can be found &lt;a href="https://gist.github.com/SkySingh04/39c061ce1cb78c092bfd72188ef9caa4" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;I am Akash Singh, a third year engineering student and Open Source Contributor from Bangalore.&lt;br&gt;
Here is my &lt;a href="https://www.linkedin.com/in/skysingh04/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, &lt;a href="https://github.com/SkySingh04" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; and &lt;a href="https://x.com/SkySingh04" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&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%2F4eayocft44kkbwoqpc8z.JPG" 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%2F4eayocft44kkbwoqpc8z.JPG" alt="Sky Singh" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I go by the name SkySingh04 online.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  Application Process
&lt;/h2&gt;

&lt;p&gt;The LFX Mentorship application journey began in December 2024 when applications opened for the 2025 Term 1 (March-May) cohort. The process was both exciting and nerve-wracking as I navigated through multiple project applications.&lt;/p&gt;
&lt;h3&gt;
  
  
  Projects I Applied To
&lt;/h3&gt;

&lt;p&gt;Having prior open-source contributions gave me the confidence to apply to three CNCF projects:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://mentorship.lfx.linuxfoundation.org/project/445a6158-3ba7-429e-b0e1-f7417ff9a724" rel="noopener noreferrer"&gt;LitmusChaos: CI/CD Integration, SDK Development &amp;amp; Chaos-CI-Lib Revamp&lt;/a&gt;&lt;/strong&gt; - This project aimed to revolutionize the CI/CD experience for chaos engineering by developing a dedicated SDK and modernizing the Chaos-CI-Lib for Litmus 3.x compatibility.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://mentorship.lfx.linuxfoundation.org/project/012a9fb4-286b-4a76-ad7a-2de644427109" rel="noopener noreferrer"&gt;KCL: KPM &amp;amp; LSP Integrated&lt;/a&gt;&lt;/strong&gt; - Focused on strengthening the integration between Language Server Protocol (LSP) and KCL Package Manager (KPM) for better IDE experience.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="http://mentorship.lfx.linuxfoundation.org/project/8d2d522f-8838-4baa-9be4-d13dab30289b" rel="noopener noreferrer"&gt;Karmada: Self-Signed Certificate Content Standardization&lt;/a&gt;&lt;/strong&gt; - Aimed at enhancing Karmada's certificate system compliance by ensuring each component has distinct certificates.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Application Requirements
&lt;/h3&gt;

&lt;p&gt;The LFX portal required two components for the project's I appiled to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Resume&lt;/strong&gt;: Highlighting relevant technical skills and open-source contributions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cover Letter&lt;/strong&gt;: Explaining my motivation and how my skills aligned with each project&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Note that these vary from org to org. Many orgs also conduct an interview round / give additional onboarding tasks that you have to complete.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  The Selection
&lt;/h3&gt;

&lt;p&gt;After weeks of anticipation, I received the selection email in late February 2025! The mentors - &lt;a href="https://github.com/ispeakc0de" rel="noopener noreferrer"&gt;Shubham Chaudhary&lt;/a&gt; and [Vedant &lt;a href="https://github.com/Jonsy13" rel="noopener noreferrer"&gt;https://github.com/Jonsy13&lt;/a&gt;) from LitmusChaos - had evaluated all applications and selected me for the chaos engineering project. &lt;/p&gt;

&lt;p&gt;What made my application stand out was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;My existing contributions to Karmada and KCL, demonstrating familiarity with CNCF projects&lt;/li&gt;
&lt;li&gt;Strong Go programming skills essential for SDK development&lt;/li&gt;
&lt;li&gt;Understanding of Kubernetes and CI/CD pipelines&lt;/li&gt;
&lt;li&gt;Clear communication in my cover letter about how I could contribute to the project's goals&lt;/li&gt;
&lt;/ul&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%2F8wbv715apy3cb309q57t.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%2F8wbv715apy3cb309q57t.png" alt=" " width="800" height="257"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  What is Chaos Engineering?
&lt;/h2&gt;

&lt;p&gt;This mentorship was my first deep dive into Chaos Engineering and honestly I find it such a cool concept in Software Engineering and Testing in general. The way I explain it to my juniors at &lt;a href="https://www.linkedin.com/company/point-blank-d" rel="noopener noreferrer"&gt;Point Blank&lt;/a&gt; is its' the process of experimenting on a distributed system to build confidence in the system's capability to withstand ✨circus✨ conditions in production. It's about intentionally injecting failures into your systems to discover weaknesses before they impact your customers and you get a call at 3am.&lt;/p&gt;

&lt;p&gt;It is as simple as a fire drill for your infrastructure - you don't wait for an actual fire to test your emergency procedures. Similarly, chaos engineering helps you proactively identify and fix potential issues (what I refer to as ✨circus✨ conditions).&lt;/p&gt;

&lt;p&gt;Me teaching my juniors at &lt;a href="https://www.linkedin.com/company/point-blank-d" rel="noopener noreferrer"&gt;Point Blank&lt;/a&gt; about Chaos Engineering &lt;br&gt;
&lt;iframe class="tweet-embed" id="tweet-1928079304451313876-778" src="https://platform.twitter.com/embed/Tweet.html?id=1928079304451313876"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1928079304451313876-778');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1928079304451313876&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;h2&gt;
  
  
  Why LitmusChaos?
&lt;/h2&gt;

&lt;p&gt;LitmusChaos is a CNCF incubating project that makes chaos engineering easy for developers and SREs. What makes it special:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloud-Native&lt;/strong&gt;: Built specifically for Kubernetes environments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extensible&lt;/strong&gt;: Large library of pre-built experiments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitOps Friendly&lt;/strong&gt;: Declarative chaos workflows&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enterprise Ready&lt;/strong&gt;: RBAC, audit logs, and multi-tenancy support&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When I first encountered LitmusChaos, I was fascinated by how it democratizes chaos engineering, making it accessible to teams of all sizes.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Project: Modernizing LitmusChaos from 1.0 to 3.0 Approach
&lt;/h2&gt;

&lt;p&gt;My mentorship project focused on three critical areas:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;SDK Development&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;I built a comprehensive Go SDK from scratch that provides a programmatic interface to LitmusChaos. This SDK enables developers to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authenticate and manage projects&lt;/li&gt;
&lt;li&gt;Create and execute chaos experiments&lt;/li&gt;
&lt;li&gt;Manage infrastructure and environments&lt;/li&gt;
&lt;li&gt;Monitor experiment status in real-time&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;CI/CD Integration&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;I revamped the Chaos-CI-Lib to align with Litmus 3.0, transitioning from direct Kubernetes API calls to a cleaner SDK-based approach. This included:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Refactoring the entire codebase from 1.0 approach to 3.0 approach that uses our SDK.&lt;/li&gt;
&lt;li&gt;Removing direct invocations of K8s API Calls with our SDK approach.&lt;/li&gt;
&lt;li&gt;Running and testing over 13 experiments end to end with the refactoring.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. &lt;strong&gt;Template Optimization&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Updated GitHub Actions and GitLab CI templates to work seamlessly with Litmus 3.0, adding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enhanced configuration options&lt;/li&gt;
&lt;li&gt;Better infrastructure management&lt;/li&gt;
&lt;li&gt;Comprehensive probe configurations&lt;/li&gt;
&lt;/ul&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%2Frvun9yumeqzgm6bkfef0.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%2Frvun9yumeqzgm6bkfef0.png" alt=" " width="800" height="249"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  My Experience: From Zero to Chaos Engineer
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Learning Curve
&lt;/h3&gt;

&lt;p&gt;Coming into this project, I had experience with Go and Kubernetes, but chaos engineering was new to me. The first few weeks were intense - understanding GraphQL APIs, diving deep into Kubernetes operators, and grasping the architecture of a distributed chaos engineering platform.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Achievements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Built a production-ready SDK&lt;/strong&gt;: The litmus-go-sdk now serves as the foundation for all programmatic interactions with LitmusChaos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Refactored and Rewrote Chaos-Ci-Lib&lt;/strong&gt;: Rewrote and released the new version of chaos-ci-lib with our Litmus 3.0 approach using our fancy new SDK.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Modernized CI/CD workflows&lt;/strong&gt;: Reduced setup complexity for users integrating chaos testing into their pipelines on both Github Actions and Gitlab Pipelines.&lt;/li&gt;
&lt;/ul&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%2Fkfrr6ye76vae7yryhjhx.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%2Fkfrr6ye76vae7yryhjhx.png" alt=" " width="800" height="244"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Gratitude
&lt;/h2&gt;

&lt;p&gt;This incredible journey wouldn't have been possible without:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Shubham Chaudhary&lt;/strong&gt; (&lt;a href="https://github.com/ispeakc0de" rel="noopener noreferrer"&gt;@ispeakc0de&lt;/a&gt;) - For his patient guidance and code reviews that taught me industry best practices&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vedant Shrotria&lt;/strong&gt; (&lt;a href="https://github.com/Jonsy13" rel="noopener noreferrer"&gt;@Jonsy13&lt;/a&gt;) - For helping me understand the deeper architecture of LitmusChaos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sayan Mondal&lt;/strong&gt; (&lt;a href="https://www.linkedin.com/in/s-ayanide/" rel="noopener noreferrer"&gt;@S-ayanide&lt;/a&gt;) - For coordinating the mentorship program and ensuring smooth progress&lt;/li&gt;
&lt;/ul&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%2Ftvsjc3vrvicxqh2t4soa.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%2Ftvsjc3vrvicxqh2t4soa.png" alt=" " width="800" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Special thanks to the entire LitmusChaos community for being welcoming and supportive throughout my journey.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;The LFX mentorship program has been the most rewarding experience of my year. It has transformed me from a beginner in chaos engineering to a confident contributor capable of making meaningful improvements. This experience enhanced my technical understanding of chaos engineering and helped me get insights into my code and infrastructure. I have learned that anything is achievable with the right amount of energy and time. &lt;/p&gt;

&lt;p&gt;My journey with LitmusChaos doesn't end here - I'm committed to continuing my contributions to the project. I plan to maintain the SDK, help onboard new contributors, work on new features, and contribute to the ecosystem's growth. The mentorship might be ending, but my involvement with the LitmusChaos community is just beginning!&lt;/p&gt;

&lt;p&gt;Don't hesitate to apply for this mentorship for the next quarter - it could be the start of your own incredible open-source journey!&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>mentorship</category>
      <category>go</category>
      <category>cloud</category>
    </item>
    <item>
      <title>How I reduced $10000 Monthly AWS Glue Bill to $400 using Airflow</title>
      <dc:creator>Akash Singh</dc:creator>
      <pubDate>Sat, 15 Feb 2025 12:38:50 +0000</pubDate>
      <link>https://forem.com/skysingh04/how-i-reduced-10000-monthly-aws-glue-bill-to-400-using-airflow-147k</link>
      <guid>https://forem.com/skysingh04/how-i-reduced-10000-monthly-aws-glue-bill-to-400-using-airflow-147k</guid>
      <description>&lt;p&gt;During my time as a Devops Engineer at &lt;a href="https://www.linkedin.com/posts/skysingh04_newintern-devops-aws-activity-7281995442278572033-zMkh" rel="noopener noreferrer"&gt;Vance&lt;/a&gt;, we were running around 80 ETL  pipelines on &lt;strong&gt;AWS Glue&lt;/strong&gt;, but as our workloads scaled, so did our costs—hitting a staggering &lt;strong&gt;$10,000 per month&lt;/strong&gt;. This wasn’t sustainable. After analyzing our pipeline, we realized that AWS Glue's serverless nature was costing us heavily for idle time and unnecessary compute&lt;/p&gt;

&lt;p&gt;To fix this, I migrated our ETL workloads to &lt;strong&gt;Apache Airflow&lt;/strong&gt;, running on EC2 instances with ECS, and orchestrated everything using Terraform. The result? A &lt;strong&gt;96% cost reduction&lt;/strong&gt;, bringing our bill down to just &lt;strong&gt;$400 per month&lt;/strong&gt;, without compromising on performance.  &lt;/p&gt;

&lt;p&gt;While Airflow is a great alternative to Glue, &lt;u&gt;there's little documentation on setting it up properly with Terraform with Celery Executor&lt;/u&gt; — especially for cost optimization. This blog walks you through how we did it, the challenges we faced, and how you can do the same to slash your AWS Glue costs.  &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%2Fh6qcnjt10w5y12atrhg3.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%2Fh6qcnjt10w5y12atrhg3.png" alt=" " width="800" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Needless to say, this was indeed a war, credits to my manager &lt;a href="https://www.linkedin.com/in/rishabhlakhotia/" rel="noopener noreferrer"&gt;Rishabh Lakhotia&lt;/a&gt; who went through this circus with me, you are indeed a god sir.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;I am Akash Singh, a third year engineering student and Open Source Contributor from Bangalore.&lt;br&gt;
Here is my &lt;a href="https://www.linkedin.com/in/skysingh04/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, &lt;a href="https://github.com/SkySingh04" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; and &lt;a href="https://x.com/SkySingh04" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&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%2F4eayocft44kkbwoqpc8z.JPG" 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%2F4eayocft44kkbwoqpc8z.JPG" alt="Sky Singh" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I go by the name SkySingh04 online.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  The three parts of the pain
&lt;/h2&gt;

&lt;p&gt;Migrating from &lt;strong&gt;AWS Glue&lt;/strong&gt; to &lt;strong&gt;Apache Airflow&lt;/strong&gt; involves setting up three core components:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Webserver&lt;/strong&gt; – The UI for managing DAGs (Directed Acyclic Graphs) and monitoring job execution.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scheduler&lt;/strong&gt; – Responsible for triggering and scheduling DAG runs.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Workers&lt;/strong&gt; – Execute the actual tasks in the DAGs.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Using &lt;strong&gt;Terraform&lt;/strong&gt;, we provisioned ECS to run all three parallely and enable them to communicate with each other, which we will get to next.&lt;/p&gt;

&lt;p&gt;Once Airflow is up and running, the next step is to &lt;strong&gt;migrate our ETL workflows&lt;/strong&gt;. We will Glue jobs into &lt;strong&gt;Airflow DAGs&lt;/strong&gt;, and then &lt;strong&gt;nuke the the Glue jobs&lt;/strong&gt;, marking the final step in cutting down our AWS costs.  &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%2Fu8kk9fbwfkxh4booxs34.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%2Fu8kk9fbwfkxh4booxs34.png" alt=" " width="800" height="216"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The Magical Dockerfile
&lt;/h2&gt;

&lt;p&gt;You can use the following Dockerfile and push it to ECR and reference it in the upcoming configs :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM apache/airflow:latest-python3.9
USER root
RUN apt-get update &amp;amp;&amp;amp; \
    apt-get install -y --no-install-recommends \
    git \
    &amp;amp;&amp;amp; apt-get clean \
    &amp;amp;&amp;amp; rm -rf /var/lib/apt/lists/*

RUN mkdir -p /opt/airflow/dags /opt/airflow/logs &amp;amp;&amp;amp; \
    chown -R airflow:root /opt/airflow &amp;amp;&amp;amp; \
    chmod -R 755 /opt/airflow/logs


USER airflow

RUN pip install --no-cache-dir \
    apache-airflow-providers-github \
    apache-airflow-providers-amazon \
    apache-airflow-providers-mysql \
    apache-airflow-providers-mongo \
    apache-airflow[celery,redis] \
    pandas

COPY --chown=airflow:root dags/* /opt/airflow/dags/

ENV AIRFLOW__LOGGING__BASE_LOG_FOLDER=/opt/airflow/logs \
    AIRFLOW__LOGGING__WORKER_LOG_SERVER_PORT=8793 \
    AIRFLOW__LOGGING__LOGGING_LEVEL=INFO \
    AIRFLOW__LOGGING__LOG_FORMAT='[%(asctime)s] {%(filename)s:%(lineno)d} %(levelname)s - %(message)s' \
    AIRFLOW__LOGGING__SIMPLE_LOG_FORMAT='%(asctime)s %(levelname)s - %(message)s' \
    AIRFLOW__LOGGING__DAG_PROCESSOR_LOG_TARGET=file \
    AIRFLOW__LOGGING__TASK_LOG_READER=task \
    AIRFLOW__LOGGING__DAG_FILE_PROCESSOR_LOG_TARGET=/opt/airflow/logs/dag_processor_manager/dag_processor_manager.log \
    AIRFLOW__LOGGING__DAG_PROCESSOR_MANAGER_LOG_LOCATION=/opt/airflow/logs/dag_processor_manager/dag_processor_manager.log

ENV AIRFLOW__CORE__DAGS_FOLDER=/opt/airflow/dags

RUN mkdir -p /opt/airflow/logs/scheduler \
            /opt/airflow/logs/web \
            /opt/airflow/logs/worker \
            /opt/airflow/logs/dag_processor_manager \
            /opt/airflow/logs/task_logs


USER root
RUN chown -R airflow:root /opt/airflow &amp;amp;&amp;amp; \
    chmod -R 755 /opt/airflow
USER airflow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This Dockerfile will be used for all three of our components and very nicely setups logging as well. The DAGs are directly baked into the Docker Image, we will get to that in a bit. Builld the image, tag it, push it to ECR and move to the next step!&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1880591497571246356-981" src="https://platform.twitter.com/embed/Tweet.html?id=1880591497571246356"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1880591497571246356-981');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1880591497571246356&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;h2&gt;
  
  
  Airflow Web Server
&lt;/h2&gt;

&lt;p&gt;A Terraform script can be written to set up &lt;strong&gt;Apache Airflow&lt;/strong&gt; on AWS using &lt;strong&gt;ECS (Elastic Container Service) with EC2 launch type&lt;/strong&gt;. We need to make sure to add: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;CloudWatch Logging&lt;/strong&gt;:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creates a log group (&lt;code&gt;/ecs/airflow&lt;/code&gt;) with a retention of 3 days.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Security Groups&lt;/strong&gt;:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Allows inbound HTTP (port 80) and HTTPS (port 443) traffic for the Application Load Balancer (ALB).
&lt;/li&gt;
&lt;li&gt;Enables unrestricted outbound traffic.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;TLS/SSL with ACM &amp;amp; Route 53&lt;/strong&gt;:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Provisions an ACM (AWS Certificate Manager) certificate for &lt;strong&gt;airflow.internal.example.com&lt;/strong&gt; using DNS validation.
&lt;/li&gt;
&lt;li&gt;Configures Route 53 DNS records to resolve the Airflow URL to the ALB.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Application Load Balancer (ALB)&lt;/strong&gt;:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creates an &lt;strong&gt;internal ALB&lt;/strong&gt; for the Airflow webserver, supporting IPv4 &amp;amp; IPv6 (&lt;code&gt;dualstack&lt;/code&gt;).
&lt;/li&gt;
&lt;li&gt;Configures an HTTP listener (port 80) to &lt;strong&gt;redirect&lt;/strong&gt; traffic to HTTPS (port 443).
&lt;/li&gt;
&lt;li&gt;Sets up an HTTPS listener (port 443) to forward requests to the ECS target group.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ECS Task Definition for Airflow Webserver&lt;/strong&gt;:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Defines an ECS task for the &lt;strong&gt;Airflow webserver&lt;/strong&gt; running on an &lt;strong&gt;EC2-backed ECS cluster&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Uses a &lt;strong&gt;Docker image&lt;/strong&gt; stored in AWS ECR (&lt;code&gt;aws_ecr_repository.airflow.repository_url:latest&lt;/code&gt;).
&lt;/li&gt;
&lt;li&gt;Allocates &lt;strong&gt;2GB memory&lt;/strong&gt; (&lt;code&gt;2048MB&lt;/code&gt;).
&lt;/li&gt;
&lt;li&gt;Maps &lt;strong&gt;container port 8080&lt;/strong&gt; to the host for web access.
&lt;/li&gt;
&lt;li&gt;Defines a &lt;strong&gt;health check&lt;/strong&gt; (&lt;code&gt;http://localhost:8080/health&lt;/code&gt;).
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ECS Service for Airflow&lt;/strong&gt;:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creates an ECS service named &lt;strong&gt;"airflow-webserver"&lt;/strong&gt; with 1 desired task.
&lt;/li&gt;
&lt;li&gt;Associates the ECS service with the &lt;strong&gt;ALB target group&lt;/strong&gt; for load balancing.
&lt;/li&gt;
&lt;li&gt;Enables &lt;code&gt;execute-command&lt;/code&gt; to allow debugging via AWS SSM.
&lt;/li&gt;
&lt;li&gt;Uses &lt;strong&gt;a capacity provider strategy&lt;/strong&gt; for ECS resource management.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;DNS Configuration&lt;/strong&gt;:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configures a &lt;strong&gt;Route 53 A record&lt;/strong&gt; (&lt;code&gt;airflow.internal.example.com&lt;/code&gt;) pointing to the ALB.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Terraform script includes &lt;strong&gt;several environment variables&lt;/strong&gt; in the ECS task definition:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Database Connection&lt;/strong&gt; (&lt;code&gt;AIRFLOW__DATABASE__SQL_ALCHEMY_CONN&lt;/code&gt;):  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Specifies the &lt;strong&gt;PostgreSQL&lt;/strong&gt; database connection string for Airflow’s metadata database.
&lt;/li&gt;
&lt;li&gt;Uses AWS &lt;strong&gt;KMS-encrypted secrets&lt;/strong&gt; to &lt;strong&gt;securely store&lt;/strong&gt; the database password.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;User Management&lt;/strong&gt;:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;_AIRFLOW_WWW_USER_CREATE&lt;/code&gt;: Ensures the default Airflow web user is created.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;_AIRFLOW_WWW_USER_USERNAME&lt;/code&gt;: Sets the username (default: &lt;code&gt;airflow&lt;/code&gt;).
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;_AIRFLOW_WWW_USER_PASSWORD&lt;/code&gt;: Stores the password securely via AWS KMS secrets.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Security &amp;amp; Web Configuration&lt;/strong&gt;:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;AIRFLOW__WEBSERVER__EXPOSE_CONFIG&lt;/code&gt;: Enables exposing Airflow configuration via the web UI.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;AIRFLOW__SCHEDULER__ENABLE_HEALTH_CHECK&lt;/code&gt;: Enables a built-in scheduler health check.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Database Migrations &amp;amp; Initialization&lt;/strong&gt;:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;_AIRFLOW_DB_MIGRATE&lt;/code&gt;: Ensures Airflow runs necessary database migrations on startup.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now go ahead and run &lt;code&gt;terraform plan&lt;/code&gt; and &lt;code&gt;terraform apply&lt;/code&gt; and you should see a lot of resources being created. If everything went correctly, you will see the airflow ui on the url you specified : &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%2F3276onoy6u3iuluqzf95.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%2F3276onoy6u3iuluqzf95.png" alt=" " width="800" height="288"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Airflow Scheduler
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Airflow Scheduler&lt;/strong&gt; is responsible for orchestrating DAG executions and ensuring scheduled tasks run at the correct time. A Terraform script can be written to  provision the &lt;strong&gt;scheduler as an ECS service&lt;/strong&gt;, configures &lt;strong&gt;CloudWatch logging&lt;/strong&gt;, and enables &lt;strong&gt;auto-scaling&lt;/strong&gt; to manage resource usage effectively.&lt;/p&gt;

&lt;p&gt;While most of this is similar to the webserver, in summary, we need to added : &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Logs Scheduler Execution in CloudWatch&lt;/strong&gt; (&lt;code&gt;/ecs/airflow-scheduler/&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitors Performance via StatsD Metrics&lt;/strong&gt; (&lt;code&gt;airflow-metrics&lt;/code&gt; namespace).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runs in an ECS Cluster with Auto Scaling&lt;/strong&gt;, ensuring efficient resource allocation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Uses CloudWatch Agent for Monitoring&lt;/strong&gt;, helping analyze task execution times.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secured by a Restricted Security Group&lt;/strong&gt;, blocking unwanted traffic.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, go ahead and run &lt;code&gt;terraform plan&lt;/code&gt; and &lt;code&gt;terraform apply&lt;/code&gt;, and the &lt;strong&gt;Airflow Scheduler&lt;/strong&gt; will be provisioned successfully! 🚀&lt;/p&gt;

&lt;h2&gt;
  
  
  Airflow Worker
&lt;/h2&gt;

&lt;p&gt;The Airflow worker service is deployed as an &lt;strong&gt;ECS service on EC2 instances&lt;/strong&gt; with &lt;strong&gt;auto-scaling&lt;/strong&gt; based on memory utilization. It runs the &lt;strong&gt;Celery workers&lt;/strong&gt;, which execute tasks from the DAGs, and will require &lt;strong&gt;Redis&lt;/strong&gt;, which we’ll set up next.  &lt;/p&gt;

&lt;p&gt;The important things to note are : &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uses &lt;strong&gt;CeleryExecutor&lt;/strong&gt;, meaning tasks are distributed among workers.
&lt;/li&gt;
&lt;li&gt;Logs are sent to &lt;strong&gt;CloudWatch&lt;/strong&gt; for monitoring.
&lt;/li&gt;
&lt;li&gt;Workers scale dynamically between &lt;strong&gt;0 and 5&lt;/strong&gt; based on &lt;strong&gt;memory utilization&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Each worker runs as a container inside &lt;strong&gt;ECS&lt;/strong&gt;, managed by an &lt;strong&gt;autoscaling policy&lt;/strong&gt; with a target of &lt;strong&gt;60% memory utilization&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;DUMB_INIT_SETSID=0&lt;/code&gt;&lt;/strong&gt; is set to handle proper signal propagation for Celery shutdown.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This entire setup made me &lt;strong&gt;cry&lt;/strong&gt; because debugging autoscaling, log management, and task execution in ECS is a nightmare. Also, Redis isn’t even here yet, so the pain is far from over.&lt;/p&gt;

&lt;h2&gt;
  
  
  Redis and RDS
&lt;/h2&gt;

&lt;p&gt;Setting up redis isn't that bad , you can use the following terraform file:&lt;br&gt;
&lt;/p&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_elasticache_subnet_group"&lt;/span&gt; &lt;span class="s2"&gt;"airflow"&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;"airflow-redis-subnet-group"&lt;/span&gt;
  &lt;span class="nx"&gt;subnet_ids&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_subnet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;airflow&lt;/span&gt;&lt;span class="p"&gt;[*].&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;merge&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;"airflow-redis-subnet-group"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;common_tags&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_security_group"&lt;/span&gt; &lt;span class="s2"&gt;"airflow_redis"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;name_prefix&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"airflow-redis"&lt;/span&gt;
  &lt;span class="nx"&gt;vpc_id&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aws_vpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;

  &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;merge&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;"airflow-redis"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;common_tags&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_security_group_rule"&lt;/span&gt; &lt;span class="s2"&gt;"airflow_redis_inbound"&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="s2"&gt;"ingress"&lt;/span&gt;
  &lt;span class="nx"&gt;from_port&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;6379&lt;/span&gt;
  &lt;span class="nx"&gt;to_port&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;6379&lt;/span&gt;
  &lt;span class="nx"&gt;protocol&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;
  &lt;span class="nx"&gt;cidr_blocks&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aws_vpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cidr_block&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;security_group_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_security_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;airflow_redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&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;"Allow Redis from internal network"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_elasticache_cluster"&lt;/span&gt; &lt;span class="s2"&gt;"airflow"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;cluster_id&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"airflow"&lt;/span&gt;
  &lt;span class="nx"&gt;engine&lt;/span&gt;               &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"redis"&lt;/span&gt;
  &lt;span class="nx"&gt;node_type&lt;/span&gt;            &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"cache.t4g.small"&lt;/span&gt;
  &lt;span class="nx"&gt;num_cache_nodes&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="nx"&gt;parameter_group_name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"default.redis5.0"&lt;/span&gt;
  &lt;span class="nx"&gt;engine_version&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"5.0.6"&lt;/span&gt;
  &lt;span class="nx"&gt;port&lt;/span&gt;                 &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;6379&lt;/span&gt;
  &lt;span class="nx"&gt;subnet_group_name&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_elasticache_subnet_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;airflow&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;security_group_ids&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_security_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;airflow_redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;merge&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;"airflow-redis-server"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;common_tags&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_security_group_rule"&lt;/span&gt; &lt;span class="s2"&gt;"airflow_redis_outbound"&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="s2"&gt;"egress"&lt;/span&gt;
  &lt;span class="nx"&gt;from_port&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="nx"&gt;to_port&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="nx"&gt;protocol&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"-1"&lt;/span&gt;
  &lt;span class="nx"&gt;cidr_blocks&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"0.0.0.0/0"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;security_group_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_security_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;airflow_redis&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And similarly, we will setup RDS as well for airflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Security Groups&lt;/span&gt;
&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_security_group"&lt;/span&gt; &lt;span class="s2"&gt;"airflow_rds"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;lifecycle&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;create_before_destroy&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;name_prefix&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"airflow-rds-default-"&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;"Allow TLS inbound traffic and all outbound traffic for airflow"&lt;/span&gt;
  &lt;span class="nx"&gt;vpc_id&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aws_vpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;

  &lt;span class="nx"&gt;tags&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;"airflow-rds-default"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_security_group_rule"&lt;/span&gt; &lt;span class="s2"&gt;"airflow_rds_inbound"&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="s2"&gt;"ingress"&lt;/span&gt;
  &lt;span class="nx"&gt;from_port&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="nx"&gt;to_port&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="nx"&gt;protocol&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"-1"&lt;/span&gt;
  &lt;span class="nx"&gt;cidr_blocks&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aws_vpc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cidr_block&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;security_group_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_security_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;airflow_rds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&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;"Allow all from internal network"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_db_subnet_group"&lt;/span&gt; &lt;span class="s2"&gt;"airflow"&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;"postgres-airflow"&lt;/span&gt;
  &lt;span class="nx"&gt;subnet_ids&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_subnet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;airflow&lt;/span&gt;&lt;span class="p"&gt;[*].&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_db_instance"&lt;/span&gt; &lt;span class="s2"&gt;"airflow"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;db_name&lt;/span&gt;                    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"any db name"&lt;/span&gt;
  &lt;span class="nx"&gt;apply_immediately&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;allocated_storage&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"100"&lt;/span&gt;
  &lt;span class="nx"&gt;storage_type&lt;/span&gt;               &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"gp3"&lt;/span&gt;
  &lt;span class="nx"&gt;engine&lt;/span&gt;                     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"postgres"&lt;/span&gt;
  &lt;span class="nx"&gt;engine_version&lt;/span&gt;             &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"17.2"&lt;/span&gt;
  &lt;span class="nx"&gt;auto_minor_version_upgrade&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;instance_class&lt;/span&gt;             &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"db.t4g.micro"&lt;/span&gt;
  &lt;span class="nx"&gt;username&lt;/span&gt;                   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"airflow"&lt;/span&gt;
  &lt;span class="nx"&gt;password&lt;/span&gt;                   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;aws_kms_secrets&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;airflow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;plaintext&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"db_password"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;multi_az&lt;/span&gt;                   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="nx"&gt;publicly_accessible&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="nx"&gt;deletion_protection&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="nx"&gt;skip_final_snapshot&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;identifier&lt;/span&gt;                 &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"airflow"&lt;/span&gt;
  &lt;span class="nx"&gt;vpc_security_group_ids&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_security_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;airflow_rds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nx"&gt;db_subnet_group_name&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_db_subnet_group&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;airflow&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go ahead and create all of these resources as well using terraform!&lt;/p&gt;

&lt;h2&gt;
  
  
  The ENV Configurations to make all of this work
&lt;/h2&gt;

&lt;p&gt;To make &lt;strong&gt;Airflow work properly in ECS with CeleryExecutor&lt;/strong&gt;, several environment variables are required for &lt;strong&gt;logging, task execution, database connections, Redis as the message broker, and external integrations&lt;/strong&gt;. These are defined in &lt;strong&gt;Terraform locals&lt;/strong&gt; and passed into the Airflow containers.  &lt;/p&gt;




&lt;p&gt;&lt;strong&gt;1️⃣ Core Airflow Configuration&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Instance Name:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;"AIRFLOW__WEBSERVER__INSTANCE_NAME" = "airflow-webserver"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Helps identify the webserver instance.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Executor:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;"AIRFLOW__CORE__EXECUTOR" = "CeleryExecutor"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Uses &lt;strong&gt;CeleryExecutor&lt;/strong&gt; to distribute tasks across multiple workers instead of running them sequentially in a single instance.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Database Connection:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;"AIRFLOW__CORE__SQL_ALCHEMY_CONN"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Connects to &lt;strong&gt;PostgreSQL&lt;/strong&gt;, using credentials stored in AWS KMS secrets.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Load Examples:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;"AIRFLOW__CORE__LOAD_EXAMPLES" = "True"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Controls whether example DAGs should be loaded.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;2️⃣ Logging Configuration (AWS CloudWatch &amp;amp; S3)&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Log Level:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;"AIRFLOW__LOGGING__LOGGING_LEVEL" = "DEBUG"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Enables verbose logging for debugging.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Remote Logging to CloudWatch:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;"AIRFLOW__LOGGING__REMOTE_LOGGING" = "True"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;"AIRFLOW__LOGGING__REMOTE_LOG_CONN_ID" = "aws_conn"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;"AIRFLOW__LOGGING__REMOTE_BASE_LOG_FOLDER" = "s3://abc"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Stores logs in &lt;strong&gt;S3 and CloudWatch&lt;/strong&gt;, making them accessible even if containers restart.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;3️⃣ Celery &amp;amp; Redis Configuration (Message Queue &amp;amp; Task Result Storage)&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Message Queue (Redis):&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;"AIRFLOW__CELERY__BROKER_URL" = "redis://${aws_elasticache_cluster.airflow.cache_nodes[0].address}:6379/0"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Celery uses &lt;strong&gt;Redis&lt;/strong&gt; for task queuing (yet to be set up, another source of pain).
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Task Result Storage (PostgreSQL):&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;"AIRFLOW__CELERY__RESULT_BACKEND" = "db+postgresql://airflow:${data.aws_kms_secrets.airflow.plaintext["db_password"]}@${aws_db_instance.airflow.endpoint}/airflow"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Task execution results are stored in &lt;strong&gt;PostgreSQL&lt;/strong&gt;, ensuring persistence.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Celery Transport Options:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;"AIRFLOW__CELERY_BROKER_TRANSPORT_OPTIONS__VISIBILITY_TIMEOUT" = "1800"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Ensures tasks are not marked as failed too soon.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;4️⃣ SMTP (Email Alerts for DAG Failures &amp;amp; Notifications)&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SMTP Configuration:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;"AIRFLOW__SMTP__SMTP_HOST" = "d"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;"AIRFLOW__SMTP__SMTP_MAIL_FROM" = "abc@email.com"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;"AIRFLOW__SMTP__SMTP_PORT" = "587"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;"AIRFLOW__SMTP__SMTP_SSL" = "True"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Used for sending failure notifications via &lt;strong&gt;email&lt;/strong&gt;.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;5️⃣ AWS-Specific Configurations&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Region Setting:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;"AWS_DEFAULT_REGION" = local.region&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Ensures Terraform and Airflow components run in the correct AWS region.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Fluent Bit Logging for Observability:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uses &lt;strong&gt;Fluent Bit&lt;/strong&gt; (&lt;code&gt;aws-for-fluent-bit:stable&lt;/code&gt;) for log collection.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;6️⃣ External Integrations (GitHub &amp;amp; AWS Secrets Manager)&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Connection (Airflow Providers):&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;"AIRFLOW__PROVIDERS__GITHUB__GITHUB_CONN_ID" = "github_default"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;"AIRFLOW__PROVIDERS__GITHUB__ACCESS_TOKEN" = data.aws_kms_secrets.airflow.plaintext["github_token"]&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Enables Airflow DAGs to interact with GitHub APIs.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Pain Points 😭&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Setting up Redis for Celery&lt;/strong&gt; is a &lt;strong&gt;huge&lt;/strong&gt; pain because of networking and IAM role issues.
&lt;/li&gt;
&lt;li&gt;Debugging &lt;strong&gt;log storage in S3 &amp;amp; CloudWatch&lt;/strong&gt; while handling permissions is frustrating.
&lt;/li&gt;
&lt;li&gt;Managing &lt;strong&gt;AWS Secrets Manager &amp;amp; KMS decryption&lt;/strong&gt; for credentials adds complexity.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-scaling workers&lt;/strong&gt; based on &lt;strong&gt;Redis queue depth &amp;amp; CPU/memory usage&lt;/strong&gt; needs fine-tuning.
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Okay yes lets finally move the DAGs now!
&lt;/h2&gt;

&lt;p&gt;Now that the Airflow infrastructure is mostly set up (minus the &lt;strong&gt;Redis pain&lt;/strong&gt; 😭), it's time to &lt;strong&gt;move our DAGs&lt;/strong&gt;. Instead of mounting them dynamically, we are &lt;strong&gt;baking them directly into the Docker image&lt;/strong&gt;. This ensures that every container running the Airflow scheduler or worker has the DAGs &lt;strong&gt;preloaded&lt;/strong&gt; without relying on external storage.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1️⃣ How We Bake DAGs into the Docker Image&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
In our &lt;strong&gt;Dockerfile&lt;/strong&gt; (which we wrote earlier), we add the DAGs by copying them into the &lt;code&gt;/dags&lt;/code&gt; directory inside the container&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1886127124714766686-29" src="https://platform.twitter.com/embed/Tweet.html?id=1886127124714766686"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1886127124714766686-29');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1886127124714766686&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2️⃣ Why This Approach?&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;No need for external DAG storage&lt;/strong&gt; (like S3, EFS, or Git sync).
&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Ensures version control&lt;/strong&gt;—DAGs are part of the &lt;strong&gt;Docker build process&lt;/strong&gt;, so each deployment gets a &lt;strong&gt;known&lt;/strong&gt; DAG version.
&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Simplifies deployments&lt;/strong&gt;—no extra steps to copy DAGs at runtime.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3️⃣ Building &amp;amp; Pushing the Docker Image&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Once the DAGs are added, we build and push the image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; airflow-custom:latest &lt;span class="nb"&gt;.&lt;/span&gt;
docker tag airflow-custom:latest &amp;lt;AWS_ACCOUNT_ID&amp;gt;.dkr.ecr.&amp;lt;AWS_REGION&amp;gt;.amazonaws.com/airflow:latest
docker push &amp;lt;AWS_ACCOUNT_ID&amp;gt;.dkr.ecr.&amp;lt;AWS_REGION&amp;gt;.amazonaws.com/airflow:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2F1mytv5cvbjxadjosywyu.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%2F1mytv5cvbjxadjosywyu.png" alt=" " width="800" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4️⃣ Updating ECS to Use the New Image&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Since we bake the DAGs into the image, we &lt;strong&gt;just update ECS to pull the latest image&lt;/strong&gt;, and the DAGs will be there.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ecs update-service &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--cluster&lt;/span&gt; airflow-cluster &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--service&lt;/span&gt; airflow-scheduler &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--force-new-deployment&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This triggers a &lt;strong&gt;rolling restart&lt;/strong&gt; of the scheduler, ensuring that the new DAGs are loaded.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Pain &amp;amp; Next Steps&lt;/strong&gt; 😭
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DAG Debugging:&lt;/strong&gt; If a DAG has syntax errors, ECS will restart the scheduler &lt;strong&gt;on loop&lt;/strong&gt; until it's fixed.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hot Reloading?&lt;/strong&gt; Baking DAGs means &lt;strong&gt;redeploying&lt;/strong&gt; on every DAG update—fine for now, but we might add a &lt;strong&gt;mounted volume&lt;/strong&gt; or &lt;strong&gt;Git sync&lt;/strong&gt; later.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testing DAGs Before Baking:&lt;/strong&gt; To avoid bad deployments, we should test DAGs &lt;strong&gt;locally&lt;/strong&gt; before adding them to the image.
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Final Push: DAGs Are Moving In!&lt;/strong&gt; 🏠
&lt;/h3&gt;

&lt;p&gt;DAGs are now &lt;strong&gt;inside the container&lt;/strong&gt;, meaning no runtime copying, no missing DAG issues, and &lt;strong&gt;one less thing to worry about&lt;/strong&gt;—until the next fire starts. 🔥&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1886761377832034352-972" src="https://platform.twitter.com/embed/Tweet.html?id=1886761377832034352"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1886761377832034352-972');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1886761377832034352&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;And Now I Rest on a Pile of Blood and Bodies&lt;/strong&gt; ⚰️
&lt;/h2&gt;

&lt;p&gt;It took &lt;strong&gt;two brutal days&lt;/strong&gt;, but we &lt;strong&gt;slowly closed every Glue job&lt;/strong&gt;, one by one, like a sniper picking off targets. Each shutdown was met with anticipation—&lt;strong&gt;would Airflow take over without issues, or would we be diving into yet another debugging nightmare?&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;With each transition, we watched the DAGs spin up, monitored task executions, and &lt;strong&gt;prayed that Celery wouldn't betray us&lt;/strong&gt;. Logs were combed through, retries were tweaked, and countless cups of coffee were consumed.  &lt;/p&gt;

&lt;p&gt;And finally, at the end of this war, the numbers spoke for themselves:  &lt;/p&gt;

&lt;p&gt;🚀 &lt;strong&gt;96% cost reduction&lt;/strong&gt; in Glue job expenses.&lt;br&gt;&lt;br&gt;
🔥 &lt;strong&gt;Airflow fully operational&lt;/strong&gt;, with tasks running efficiently across ECS workers.&lt;br&gt;&lt;br&gt;
💀 &lt;strong&gt;Redis survived&lt;/strong&gt; (barely), after nearly making us lose our minds.  &lt;/p&gt;

&lt;p&gt;This migration wasn’t just a deployment; it was &lt;strong&gt;a battle of wills&lt;/strong&gt;, and somehow, against all odds, we came out victorious. Now, as the dust settles, I take a breath and rest—&lt;strong&gt;not because the war is over, but because the next battle is just around the corner.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>devops</category>
      <category>beginners</category>
      <category>terraform</category>
    </item>
    <item>
      <title>The Magic behind Bzip2 : Burrows Wheeler Transform</title>
      <dc:creator>Akash Singh</dc:creator>
      <pubDate>Mon, 30 Dec 2024 12:18:19 +0000</pubDate>
      <link>https://forem.com/skysingh04/the-magic-behind-bzip2-burrows-wheeler-transform-238d</link>
      <guid>https://forem.com/skysingh04/the-magic-behind-bzip2-burrows-wheeler-transform-238d</guid>
      <description>&lt;h2&gt;
  
  
  ACM Winter School 2024
&lt;/h2&gt;

&lt;p&gt;I recently went to ACM Winter School 2024 and over there &lt;a href="https://www.linkedin.com/in/chirgjain/" rel="noopener noreferrer"&gt;Prof. Chirag Jain&lt;/a&gt; showed us how Burrows Wheeler Transform works for compression in tools like bzip2 and how it can be used to optimize Suffix Trees and Suffix Arrays. In this blog, we'll unravel the workings of the BWT and its significance, while I try to translate my class notes into this blog xD.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1873089694227141066-138" src="https://platform.twitter.com/embed/Tweet.html?id=1873089694227141066"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1873089694227141066-138');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1873089694227141066&amp;amp;theme=dark"
  }



&lt;/p&gt;

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

&lt;p&gt;I am Akash Singh, a third year engineering student and Open Source Contributor from Bangalore.&lt;br&gt;
Here is my &lt;a href="https://www.linkedin.com/in/skysingh04/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, &lt;a href="https://github.com/SkySingh04" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; and &lt;a href="https://x.com/SkySingh04" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&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%2F4eayocft44kkbwoqpc8z.JPG" 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%2F4eayocft44kkbwoqpc8z.JPG" alt="Sky Singh" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I go by the name SkySingh04 online.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h3&gt;
  
  
  What is the Burrows-Wheeler Transform?
&lt;/h3&gt;

&lt;p&gt;The BWT is a reversible text transformation that rearranges the characters of a string into runs of similar characters, making the string more amenable to compression. This transformation is pivotal in compression algorithms like bzip2 and indexing structures like the FM-index.&lt;/p&gt;

&lt;p&gt;The magic of the BWT lies in its ability to group identical characters together while retaining the original string's information, albeit in a transformed format.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1873089359106458098-729" src="https://platform.twitter.com/embed/Tweet.html?id=1873089359106458098"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1873089359106458098-729');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1873089359106458098&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;Let’s explore how BWT is applied step-by-step using the example &lt;code&gt;banana$&lt;/code&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Applying BWT on &lt;code&gt;banana$&lt;/code&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Start with a Sentinel Character&lt;/strong&gt;
Append a sentinel character &lt;code&gt;$&lt;/code&gt; at the end of the string. This character:

&lt;ul&gt;
&lt;li&gt;Marks the end of the string.&lt;/li&gt;
&lt;li&gt;Is lexicographically smaller than all other characters.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For &lt;code&gt;banana&lt;/code&gt;, we get &lt;code&gt;banana$&lt;/code&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Generate All Rotations&lt;/strong&gt;
Create all cyclic rotations of the string:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   banana$
   anana$b
   nana$ba
   ana$ban
   na$bana
   a$banan
   $banana
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Sort the Rotations Lexicographically&lt;/strong&gt;
After sorting the rotations:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   $banana
   a$banan
   ana$ban
   anana$b
   banana$
   na$bana
   nana$ba
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Extract the Last Column&lt;/strong&gt;
The last column of the sorted rotations forms the BWT:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   BWT: annb$aa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Fun Story :
&lt;/h3&gt;

&lt;p&gt;One of the best parts about attending such Winter schools are the people around you. For example, this is the gossip between me and &lt;a href="https://www.linkedin.com/in/alfiyafatima09/" rel="noopener noreferrer"&gt;Alfiya&lt;/a&gt; xD.&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%2Flan3ysrbq8dvpb5wh2fk.jpg" 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%2Flan3ysrbq8dvpb5wh2fk.jpg" alt=" " width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Yes this is real and was a meme throughout the winter school lmao.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Reversibility: Going Back to the Original Text
&lt;/h3&gt;

&lt;p&gt;One of the most fascinating aspects of BWT is its &lt;strong&gt;reversibility&lt;/strong&gt;. You can reconstruct the original string from the transformed version without losing any information. Here’s how:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Sort the BWT&lt;/strong&gt;
Create the first column by sorting the characters of the BWT. For &lt;code&gt;annb$aa&lt;/code&gt;, the sorted order is:
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Link Columns&lt;/strong&gt;
The relationship between the first and last columns allows us to reconstruct the string. By tracking character positions and their order, we recover &lt;code&gt;banana$&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;I think my notes will make more sense here&lt;/p&gt;
&lt;/blockquote&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%2Fk2j9jmlwk7072hcd9vff.jpg" 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%2Fk2j9jmlwk7072hcd9vff.jpg" alt=" " width="800" height="1066"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This lossless transformation ensures that no data is discarded during the process.&lt;/p&gt;




&lt;h3&gt;
  
  
  Succinct Indexing with BWT
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;succinct index&lt;/strong&gt; created by BWT is used in data structures like the &lt;strong&gt;FM-index&lt;/strong&gt;, which powers efficient string searching. Instead of storing the entire text, the FM-index enables queries by leveraging the BWT and auxiliary data structures like &lt;strong&gt;suffix arrays&lt;/strong&gt;. This is especially valuable for applications requiring high-speed pattern matching.&lt;/p&gt;




&lt;h3&gt;
  
  
  BWT and Suffix Trees
&lt;/h3&gt;

&lt;p&gt;In class, Prof. Chirag Jain explained how BWT interacts with &lt;strong&gt;suffix trees&lt;/strong&gt; and &lt;strong&gt;suffix arrays&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Suffix Trees&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
By applying BWT to suffix trees, we can reduce memory usage while maintaining efficient query performance. The BWT clusters repeated substrings, which aligns closely with how suffix trees group similar patterns.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Genome Indexing&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
In bioinformatics, the BWT is critical for indexing and searching genomic data. Tools like &lt;strong&gt;Bowtie&lt;/strong&gt; and &lt;strong&gt;BWA&lt;/strong&gt; rely on the FM-index (a BWT-based structure) to align DNA sequences efficiently.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Why is BWT Useful for Genomics?
&lt;/h3&gt;

&lt;p&gt;In genome sequencing, researchers often need to match short DNA sequences against massive genomic datasets. The BWT-based FM-index enables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Space Efficiency&lt;/strong&gt;: Compact representation of the genome.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fast Searching&lt;/strong&gt;: Efficient pattern matching without decompressing the data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: Handles terabytes of genomic data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, if a query DNA sequence is &lt;code&gt;AGCT&lt;/code&gt;, the BWT groups occurrences of &lt;code&gt;A&lt;/code&gt;, &lt;code&gt;G&lt;/code&gt;, &lt;code&gt;C&lt;/code&gt;, and &lt;code&gt;T&lt;/code&gt; together, making it faster to locate matches.&lt;/p&gt;




&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Burrows-Wheeler Transform&lt;/strong&gt; is not just an algorithm—it’s a gateway to understanding the interplay between mathematics and computer science. From powering compression tools like &lt;strong&gt;bzip2&lt;/strong&gt; to optimizing bioinformatics pipelines, BWT continues to revolutionize how we process and store data.&lt;/p&gt;

&lt;p&gt;Attending ACM Winter School 2024 gave me a fresh perspective on how these elegant algorithms shape our world. If you’re interested in exploring string algorithms, BWT is the perfect starting point, right after Suffix Trees and Suffix Trees. Also I'll be willing to sell my winter school notes, the bidding starts at 69 bucks xD.&lt;/p&gt;

</description>
      <category>codenewbie</category>
      <category>algorithms</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>A Lab Manual to Devops</title>
      <dc:creator>Akash Singh</dc:creator>
      <pubDate>Thu, 19 Dec 2024 18:35:08 +0000</pubDate>
      <link>https://forem.com/skysingh04/a-lab-manual-to-devops-4j0e</link>
      <guid>https://forem.com/skysingh04/a-lab-manual-to-devops-4j0e</guid>
      <description>&lt;h2&gt;
  
  
  Wait a lab manual?
&lt;/h2&gt;

&lt;p&gt;As it stands, there is an upcoming exam on devops for some very good friends of mine. And with the lack of material provided by college combined with incompetent faculties, this subject quickly became a nightmare for them.&lt;/p&gt;

&lt;p&gt;Fear not, since I was summoned to help out this crisis. Time to put some respect on the name of devops and in the process, try and make the life of some of my friends easier.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note : This handout will contain solutions and explanation for all 6 of the following questions:&lt;/p&gt;
&lt;/blockquote&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%2Fgg90vrvdnd12b8a147wi.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%2Fgg90vrvdnd12b8a147wi.png" alt=" " width="721" height="327"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This guide is written not only to help the people who are appearing for Course Code &lt;strong&gt;22CBL54&lt;/strong&gt; , but for anyone who wants to get into devops in general.&lt;/p&gt;

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

&lt;p&gt;I am Akash Singh, a third year engineering student and Open Source Contributor from Bangalore.&lt;br&gt;
Here is my &lt;a href="https://www.linkedin.com/in/skysingh04/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, &lt;a href="https://github.com/SkySingh04" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; and &lt;a href="https://x.com/SkySingh04" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&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%2F4eayocft44kkbwoqpc8z.JPG" 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%2F4eayocft44kkbwoqpc8z.JPG" alt="Sky Singh" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I go by the name SkySingh04 online.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  What is DevOps Again?
&lt;/h2&gt;

&lt;p&gt;DevOps is the buzzword you can't escape, and for good reason. It's a blend of &lt;em&gt;Development&lt;/em&gt; and &lt;em&gt;Operations—a methodology aimed at **streamlining the software development lifecycle (SDLC)&lt;/em&gt; by improving collaboration between developers and IT operations teams.&lt;/p&gt;

&lt;p&gt;Think of DevOps as a recipe where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Dev = Building the dish (coding)&lt;/li&gt;
&lt;li&gt;  Ops = Serving it piping hot to hungry users (deployment and maintenance)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Why Should You Care?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt; &lt;em&gt;Speed&lt;/em&gt;: Faster delivery of features.&lt;/li&gt;
&lt;li&gt; &lt;em&gt;Collaboration&lt;/em&gt;: No more blaming each other—“It works on my machine” doesn’t fly here.&lt;/li&gt;
&lt;li&gt; &lt;em&gt;Reliability&lt;/em&gt;: Fewer bugs in production (touch wood).&lt;/li&gt;
&lt;li&gt; &lt;em&gt;Scalability&lt;/em&gt;: Handle user traffic like a boss.&lt;/li&gt;
&lt;li&gt; &lt;em&gt;Security&lt;/em&gt;: Automate boring-but-important security checks.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Hope that makes sense? Basically if the app crashes on production, first they will come eat my head and ask me what is wrong. As a devops engineer, since I have setup the pipeline for the deployment, I should be able to look at the monitoring tools or the logs or the infra and tell them okay this is the guy who fucked up (9/10 times its the developer, 1/10 times I done the goof while setting up the infra or pipeline hehe)&lt;/p&gt;

&lt;p&gt;Okay I hope it makes sense now, basically we devops engineers are a cross breed and think we are the &lt;em&gt;main characters&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Okay now the premise is set, lets get to passing this lab internals ay?&lt;/p&gt;


&lt;h2&gt;
  
  
  Question 1: GIT Operations
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Problem Statement
&lt;/h3&gt;

&lt;p&gt;To perform Git operations like creating a repository and fetching, pulling, and branching.&lt;/p&gt;
&lt;h3&gt;
  
  
  Solution
&lt;/h3&gt;
&lt;h4&gt;
  
  
  Step 1: Install Git
&lt;/h4&gt;

&lt;p&gt;Use your terminal like a pro:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update
sudo apt install git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 2: Create a Repository
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Navigate to your project folder:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd ~/your_project
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Initialize Git:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git init
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add and commit files:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git add .
git commit -m "Initial commit"
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Step 3: Fetch and Pull
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Fetch&lt;/em&gt; brings changes from the remote repository but doesn't merge them:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git fetch origin
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Pull&lt;/em&gt; fetches and merges changes:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git pull origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Step 4: Branching
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Create a new branch:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git branch feature-branch
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Switch to it:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git checkout feature-branch
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Merge back to main:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git checkout main
git merge feature-branch
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In general, pretty self explanatory program. I hope the person reading this has once in their life used &lt;em&gt;git&lt;/em&gt; . Is that too much to ask from 3rd year students? Wdym get a life Sky?&lt;/p&gt;

&lt;h2&gt;
  
  
  Question 2: The DevOps Lifecycle
&lt;/h2&gt;

&lt;p&gt;The DevOps lifecycle involves a series of stages—Code, Build, Test, Configure, and Monitor—designed to streamline the software development process.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;Code&lt;/em&gt;: Writing and managing code collaboratively.&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;Build&lt;/em&gt;: Compiling source code into executable artifacts.&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;Test&lt;/em&gt;: Automating testing to ensure code quality.&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;Configure&lt;/em&gt;: Setting up the environment for deployment.&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;Monitor&lt;/em&gt;: Tracking application health in production.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Alright, we will build a very small web app that displays "Hello, Devops!" and then implement the above 5 steps in it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is kind of a very vague question and a million ways to implement and answer this. I will try to give the simplest solution that should ideally fetch the full marks or I delete my Linkedin. &lt;/p&gt;
&lt;/blockquote&gt;




&lt;h4&gt;
  
  
  &lt;em&gt;Step 1: Code&lt;/em&gt;
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Create the Flask Application&lt;/em&gt;&lt;br&gt;
&lt;code&gt;File: app.py&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from flask import Flask    
app = Flask(__name__)

@app.route('/')
def home():
    return "Hello, DevOps!"

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=5000)
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Set Up a Virtual Environment&lt;/em&gt;&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python3 -m venv venv
source venv/bin/activate  # Linux/Mac
venv\Scripts\activate  # Windows

pip install flask

pip freeze &amp;gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Run the Application&lt;/em&gt;&lt;br&gt;
    &lt;code&gt;python app.py&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open in your browser: &lt;a href="http://localhost:5000" rel="noopener noreferrer"&gt;http://localhost:5000&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;Step 2: Build&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;If you know, Python is an interpreted language. There is no build step so to speak, since the code gets executed line by line. So here, &lt;em&gt;build&lt;/em&gt; refers to the preparation of the environment and making sure the app is ready to run.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;We will write a simple &lt;em&gt;shell script&lt;/em&gt; (build.sh) to install dependencies and ensure the app runs:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash
echo "Setting up environment..."
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
echo "Environment setup complete. Run the app with: python app.py"
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run the script:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bash build.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  &lt;em&gt;Step 3: Test&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Now since the program demands we write some test, we will write a very simple test that checks if the app is running or not. Btw shameless plugin but if you want to write tests with 0 code, checkout my &lt;a href="https://marketplace.visualstudio.com/items?itemName=Keploy.keployio" rel="noopener noreferrer"&gt;Keploy Vscode Extension xD&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;**Test File (test_app.py):&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import unittest
from app import app

class TestApp(unittest.TestCase):
    def test_home(self):
        tester = app.test_client(self)
        response = tester.get('/')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data, b"Hello, DevOps!")

if __name__ == "__main__":
    unittest.main()
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run the tests:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python -m unittest test_app.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  &lt;em&gt;Step 4: Configure&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Configuration here focuses on making sure the app can run in different environments. One simple approach is to use &lt;em&gt;environment variables&lt;/em&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create a .env file:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FLASK_PORT=5000
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Modify app.py to read the environment variable:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import os
from flask import Flask

app = Flask(__name__)

@app.route('/')
def home():
    return "Hello, DevOps!"

if __name__ == "__main__":
    port = int(os.getenv("FLASK_PORT", 5000))
    app.run(port=port)
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use python-dotenv to automatically load .env files:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install python-dotenv
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add to app.py:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from dotenv import load_dotenv

load_dotenv()
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  &lt;em&gt;Step 5: Monitor&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Now monitoring is very very complicated when you bring in fancy tools like Prometheus , Grafana, Loki etc. Implementing all of that is beyond the scope of this beginner's guide . Monitoring in general means just seeing what the app is doing while it is running , like logs, health , any errors etc. We will integrate some basic monitoring without external tools:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Add a /health endpoint&lt;/strong&gt; to check if the app is running:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@app.route('/health')
def health():
    return {"status": "up"}, 200
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Log requests&lt;/em&gt; to a file:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import logging

logging.basicConfig(filename='app.log', level=logging.INFO)

@app.before_request
def log_request():
    logging.info(f"Request: {request.method} {request.path}")
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now when the faculty asks where monitoring, show him the localhost:5000/health path and the app.log file. Let him be happy because again, things can get very complicated here if we want them to be fancy.&lt;/p&gt;

&lt;h4&gt;
  
  
  So what exactly did we do?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;Code&lt;/em&gt;: Python Flask app built with basic coding practices.&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;Build&lt;/em&gt;: Prepared the environment with a venv and a build script.&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;Test&lt;/em&gt;: Used Python’s unittest to verify the app’s behavior.&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;Configure&lt;/em&gt;: Used .env and python-dotenv for managing environment variables.&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;Monitor&lt;/em&gt;: Added a /health endpoint and request logging.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that’s how we do &lt;em&gt;DevOps the easy way&lt;/em&gt;! 🎉&lt;/p&gt;




&lt;h2&gt;
  
  
  Question 3: Continuous Integration with Jenkins
&lt;/h2&gt;

&lt;p&gt;Now what's this new circus Jenkins? Remember when i said that as a devops guy, I have to setup the pipeline to ensure the app / code gets deployed? Yes so that pipeline is usually built using github actions and in fancier companies, they use this tool called &lt;em&gt;Jenkins&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Steps to Install Jenkins :
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;This should already be done in your lab system, if not tell your faculty that hey jenkins not installed or look up the installation instructions online , don't memorize this. Only the command to start jenkins.&lt;br&gt;
Remember you need an existing app to deploy it using jenkins, for simplicity I am using the same python app we built in Q2. It needs to be pushed to github as you'll need to connect the pipeline to your repo.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Install Java (required for Jenkins):&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update
sudo apt install openjdk-11-jdk
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Add the Jenkins Repository:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -fsSL https://pkg.jenkins.io/debian/jenkins.io.key | sudo tee \
/usr/share/keyrings/jenkins-keyring.asc &amp;gt; /dev/null
echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] \
https://pkg.jenkins.io/debian binary/ | sudo tee 
/etc/apt/sources.list.d/jenkins.list &amp;gt; /dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Install Jenkins:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt update
sudo apt install jenkins
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Start Jenkins and Check Status:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl start jenkins
sudo systemctl status jenkins
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Configure Jenkins
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Access Jenkins:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Open a browser and go to http://:8080 or &lt;a href="http://localhost:8080" rel="noopener noreferrer"&gt;http://localhost:8080&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Unlock Jenkins:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Use the admin password found in: (cant memorise , the password is unique always, you'll find it here)&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat /var/lib/jenkins/secrets/initialAdminPassword
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Install Recommended Plugins:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Follow the on-screen setup to install necessary plugins (e.g., Git, NodeJS, Pipeline).&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Jenkins Pipeline for a Web Application
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt; &lt;em&gt;Create a New Job:&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-   Go to Jenkins Dashboard and click *"New Item"*.
-   Choose *"Pipeline"* and give it a name.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt; &lt;em&gt;Configure Git Repository:&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-   In the Pipeline configuration, specify the repository URL:
    -   *Source Code Management* &amp;gt; Select *Git* &amp;gt; Enter your repository URL.
-   Add credentials if needed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;em&gt;Define the Pipeline Script:&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pipeline {
    agent any

    environment {
        VIRTUAL_ENV = 'venv' // Virtual environment directory
        FLASK_PORT = '5000' // Port to run the Flask app
    }

    stages {
        stage('Clone Repository') {
            steps {
                echo 'Cloning the repository...'
                git branch: 'main', url: 'https://github.com/ahanasrinath/myflaskapp.git'
            }
        }

        stage('Set Up Environment') {
            steps {
                echo 'Setting up virtual environment and installing dependencies...'
                sh '''
                python3 -m venv $VIRTUAL_ENV
                source $VIRTUAL_ENV/bin/activate
                pip install -r requirements.txt
                '''
            }
        }

        stage('Run Tests') {
            steps {
                echo 'Running unit tests...'
                sh '''
                source $VIRTUAL_ENV/bin/activate
                python -m unittest discover -s . -p "test_*.py"
                '''
            }
        }

        stage('Build and Package') {
            steps {
                echo 'Packaging the application...'
                sh '''
                tar -czf flask-app.tar.gz app.py requirements.txt .env
                '''
            }
        }

        stage('Deploy') {
            steps {
                echo 'Deploying the application...'
                sh '''
                # Copy the application to the deployment server
                scp flask-app.tar.gz user@your-server:/path/to/deployment

                # SSH into the server and deploy
                ssh user@your-server &amp;lt;&amp;lt; EOF
                cd /path/to/deployment
                tar -xzf flask-app.tar.gz
                source $VIRTUAL_ENV/bin/activate
                nohup python app.py &amp;gt; app.log 2&amp;gt;&amp;amp;1 &amp;amp;
                EOF
                '''
            }
        }
    }

    post {
        success {
            echo 'Pipeline completed successfully!'
        }
        failure {
            echo 'Pipeline failed. Check the logs for more details.'
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;NOW HERE IS THE THING.....Since we dont have a server to begin with, there is no place for jenkins to deploy our app so to speak. Which again makes me wonder why the fuck have they told y'all to deploy something without any context whatsoever as to where it should be deployed?&lt;/p&gt;

&lt;p&gt;Will the college give yall a dedicated server to deploy to? Very unlikely. Do they even know that they need to do so? Also unlikely. So take the last deploy stage with a grain of salt. &lt;/p&gt;
&lt;/blockquote&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%2Fwl9s45ydxqozvlyjohb6.jpg" 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%2Fwl9s45ydxqozvlyjohb6.jpg" alt="GitHub - ahmednuaman/meme-says-jenkins: A meme based Jenkins CI monitor" width="500" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hope this is not y'all in exam hall, its me everyday.&lt;/p&gt;

&lt;h4&gt;
  
  
  NOTE:
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;If they give you a random app to deploy with jenkins, *DO NOT PANICK. You'll realise whatever steps we have written in the jenkins file are the actual commands we executed in Q2. So, they can be replaced with any specific set of instructions for any specific app/ tech stack.&lt;/em&gt;*&lt;/p&gt;

&lt;h4&gt;
  
  
  For Ex:
&lt;/h4&gt;

&lt;p&gt;If they give you a react app, the setup environment would be replaced with just &lt;code&gt;npm install&lt;/code&gt; and the build will be replaced with &lt;code&gt;npm run build&lt;/code&gt;. Similarly for java app , it might be something different like &lt;code&gt;javac app.java&lt;/code&gt; or &lt;code&gt;gcc main.c&lt;/code&gt; for a c file.&lt;/p&gt;

&lt;p&gt;Point is not to panick, they dont know what they are teaching or the questions they are giving. As long as you write the steps more or less like the above, they will know that you have cooked something.&lt;/p&gt;




&lt;h2&gt;
  
  
  Question 4: Version Control Tools
&lt;/h2&gt;

&lt;p&gt;Git is the king here, but alternatives like &lt;em&gt;CVS&lt;/em&gt;, &lt;em&gt;RCS&lt;/em&gt;, and &lt;em&gt;Mercurial&lt;/em&gt; deserve mention. Each has its pros and cons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;RCS&lt;/em&gt;: For single-file projects.&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;CVS&lt;/em&gt;: Old-school, great for teams.&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;Mercurial&lt;/em&gt;: Git’s less famous sibling, preferred by projects like Mozilla.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Chalo , lets first install these (hopefully they are already installed in the lab computers y'all will be using). Use the brew commands for Mac and apt for linux.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;RCS&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;sudo apt install rcs&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;brew install rcs&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;CVS&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;sudo apt install cvs&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;brew install cvs&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Git&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;sudo apt install git&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;brew install git&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Mercurial&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;sudo apt install mercurial&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;brew install mercurial&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And here are the basic basic commands for all of them:&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;em&gt;1. Revision Control System (RCS)&lt;/em&gt;
&lt;/h3&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Initialize RCS directory
mkdir RCS

# Check-in a file to create its first revision
ci -u filename

# Check-out a file for editing
co -l filename

# View version history
rlog filename
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  &lt;em&gt;2. Concurrent Versions System (CVS)&lt;/em&gt;
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Initialize a repository
cvs -d /path/to/repo init

# Add a project to CVS
cvs import -m "Initial import" project_name vendor_tag release_tag

# Checkout a project
cvs checkout project_name

# Commit changes
cvs commit -m "Commit message"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  &lt;em&gt;3. Git&lt;/em&gt;
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Initialize a repository
git init

# Add files to the repository
git add .

# Commit changes
git commit -m "Initial commit"

# View history
git log

# Push changes to a remote repository
git remote add origin &amp;lt;repository-url&amp;gt;
git push -u origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  &lt;em&gt;4. Mercurial&lt;/em&gt;
&lt;/h3&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Initialize a repository
hg init

# Add files to the repository
hg add

# Commit changes
hg commit -m "Initial commit"

# View history
hg log

# Push changes to a remote repository
hg push &amp;lt;repository-url&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;h2&gt;
  
  
  Question 5: Docker Basics
&lt;/h2&gt;

&lt;p&gt;Okay little context is required as to what this &lt;em&gt;Docker&lt;/em&gt; is. Docker is the jaan of every Devops engineer. Without Docker, there is only chaos and suffering and pain.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;What is Docker?&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Docker is an open-source platform that allows you to develop, ship, and run applications inside &lt;em&gt;containers&lt;/em&gt;. Think of a container as a lightweight, portable, and consistent environment that contains everything your application needs to run—code, libraries, dependencies, and even the runtime.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;Why Use Docker?&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Basically to solve the problem of "ye code mere system pe chal raha h, but not on your system". A docker container simulates the entire environment and all the dependencies, so wherever you run the container, it will run reliably and without any circus. Now you dont have to fight that rich friend who has a mac or that nerd who lives only on linux. &lt;em&gt;Kahi bhi code likho, chalega ekdam aram se using Docker.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;em&gt;Core Concepts in Docker&lt;/em&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt; &lt;em&gt;Docker Image&lt;/em&gt;:

&lt;ul&gt;
&lt;li&gt;  A blueprint for a container.&lt;/li&gt;
&lt;li&gt;  Contains the app code, libraries, and dependencies.&lt;/li&gt;
&lt;li&gt;  Example: The image we will build using the Dockerfile.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt; &lt;em&gt;Docker Container&lt;/em&gt;:

&lt;ul&gt;
&lt;li&gt;  A running instance of a Docker image.&lt;/li&gt;
&lt;li&gt;  Isolated, lightweight, and portable.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Dockerfile&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  A text file containing the instructions to build a Docker image.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM python:3.8-slim
WORKDIR /app
COPY . .
CMD ["python", "app.py"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Docker Hub&lt;/em&gt;:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-   A cloud-based registry for sharing Docker images.
-   Think of it as "GitHub for containers."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;




&lt;p&gt;Docker is widely used in DevOps because it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Simplifies app deployment.&lt;/li&gt;
&lt;li&gt;  Works seamlessly with CI/CD pipelines.&lt;/li&gt;
&lt;li&gt;  Allows for microservices architecture, where each service runs in its own container.&lt;/li&gt;
&lt;/ul&gt;




&lt;blockquote&gt;
&lt;p&gt;Highly recommend watching this video by &lt;a href="https://youtu.be/gAkwW2tuIqE?si=PJ-yz5HPnXPm9lvX" rel="noopener noreferrer"&gt;Fireship on Docker&lt;/a&gt;  and this one by &lt;a href="https://youtu.be/J0NuOlA2xDc?si=HQBkslV81MvzHyyG" rel="noopener noreferrer"&gt;Coderized&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;IN VERY SIMPLE TERMS : Imagine you're packing for a trip:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  The &lt;em&gt;Docker Image&lt;/em&gt; is the suitcase, pre-packed with all the essentials (toothbrush, clothes, etc.).&lt;/li&gt;
&lt;li&gt;  The &lt;em&gt;Docker Container&lt;/em&gt; is you actually carrying the suitcase on your trip.&lt;/li&gt;
&lt;li&gt;  &lt;em&gt;Docker Hub&lt;/em&gt; is the store where you buy pre-packed suitcases (images).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Coming back to our lab program, how do we dockerise our python app? First download Docker Desktop from &lt;a href="https://www.docker.com/products/docker-desktop/%20and%20follow%20the%20instructions%20here%20https://docs.docker.com/desktop/setup/install/windows-install/" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now they have mentioned that you should run different container OS, which is brain dead easy:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;1. Pull Operating System Images&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Docker Hub provides a wide variety of operating system images.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Search for an OS image:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker search &amp;lt;os-name&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Example for Ubuntu:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker search ubuntu&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Pull an OS image:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker pull &amp;lt;os-name&amp;gt;:&amp;lt;tag&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Example for Ubuntu:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker pull ubuntu:latest&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  &lt;em&gt;2. Run Containers from the OS Image&lt;/em&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Run an interactive container:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker run -it &amp;lt;os-name&amp;gt;:&amp;lt;tag&amp;gt; /bin/bash&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker run -it ubuntu:latest /bin/bash&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This will give you a shell prompt inside the container.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;List running containers:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker ps&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;List all containers (including stopped ones):&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker ps -a&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Stop a running container:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker stop &amp;lt;container-id&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Remove a container:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker rm &amp;lt;container-id&amp;gt;&lt;/code&gt; &lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  &lt;em&gt;3. Building a Custom Application Container&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Now we will dockerise your flask app! &lt;em&gt;The above step 2 is not necessary for this step&lt;/em&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Create a Dockerfile in the root dir&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM python:3.8-slim

WORKDIR /app

COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt

COPY . .

CMD ["python", "app.py"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Build the Docker Image&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker build -t flask-devops-app .&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Run the Container&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker run -d -p 5000:5000 flask-devops-app&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Access the app at &lt;a href="http://localhost:5000" rel="noopener noreferrer"&gt;http://localhost:5000&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I will still write what each step does, feel free to skip if you can just memorise it:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;FROM python:3.8-slim&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;Purpose:&lt;/em&gt;
This specifies the base image for your container.

&lt;ul&gt;
&lt;li&gt;  python:3.8-slim is a lightweight version of the Python 3.8 image. It contains only the essential components required to run Python, making it smaller and faster to download.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;p&gt;&lt;code&gt;WORKDIR /app&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;Purpose:&lt;/em&gt;
This sets the working directory inside the container to /app.

&lt;ul&gt;
&lt;li&gt;  Any subsequent commands like COPY or RUN will execute relative to this directory.&lt;/li&gt;
&lt;li&gt;  It ensures your application code and dependencies stay organized in a specific directory within the container.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;p&gt;&lt;code&gt;COPY requirements.txt requirements.txt&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;Purpose:&lt;/em&gt;
This copies the requirements.txt file from your local system (host) to the /app directory inside the container.

&lt;ul&gt;
&lt;li&gt;  The requirements.txt file contains all the Python libraries your app depends on.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;p&gt;&lt;code&gt;RUN pip install -r requirements.txt&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Purpose:&lt;/em&gt;&lt;br&gt;&lt;br&gt;
This installs all the Python dependencies specified in the requirements.txt file using pip.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;For example, if your app uses Flask, the requirements.txt might contain:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;flask==2.1.2&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;p&gt;&lt;code&gt;COPY . .&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;Purpose:&lt;/em&gt;
This copies &lt;em&gt;all files&lt;/em&gt; from your local working directory (host) to the /app directory inside the container.

&lt;ul&gt;
&lt;li&gt;  It ensures your app.py and any other necessary files (e.g., templates, static assets) are available in the container.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;p&gt;&lt;code&gt;CMD ["python", "app.py"]&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;Purpose:&lt;/em&gt;
This specifies the command the container should run when it starts.

&lt;ul&gt;
&lt;li&gt;  Here, it tells Docker to execute python app.py, which starts your Flask application.&lt;/li&gt;
&lt;li&gt;  The CMD command runs the app in the foreground to keep the container alive while your app is running.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;THATS IT! YOUR DOCKER APP IS NOW ALIVE!!!&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fencrypted-tbn0.gstatic.com%2Fimages%3Fq%3Dtbn%3AANd9GcR7AAyq6v2knbYraTaTJwfdEZFa4ZkcKUXEwyYpsUaNFsgZcN2Ew3p522wTamtimAuHwRo%26usqp%3DCAU" alt="It's Alive Media" width="275" height="183"&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;em&gt;4. Manage Docker Containers and Images&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;Some extra commands because they maybe useful yk&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;View all images:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker images&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Remove an image:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker rmi &amp;lt;image-id&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Stop and remove all containers:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker stop $(docker ps -aq)
docker rm $(docker ps -aq)
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Prune unused data (stopped containers, networks, etc.):&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker system prune -a&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Question 6: Deploying Apps with Docker
&lt;/h2&gt;

&lt;p&gt;Congrats! If you have reached this far I am v. v. proud of you! Here is your reward: You dont have to study Question 6. Yes, question 5 and 6 are literally same to same steps! You can deploy the same flask app using the same step 3 here as well. For safety, here is the java implementation as well, you will need a simple hello world written in java btw, here it is:&lt;/p&gt;

&lt;h4&gt;
  
  
  Create Main.java in your project directory
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class Main {
    public static void main(String[] args) {
        System.out.println("Hello, Dockerized Java App!");
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then add the Dockerfile in the same folder : &lt;/p&gt;

&lt;h4&gt;
  
  
  Dockerfile for a Java App
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM openjdk:11
COPY . /app
WORKDIR /app
RUN javac Main.java
CMD ["java", "Main"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Explanation for the steps here are the same as the Dockerfile for our Flask app, only that instead of python commands we use java commands:&lt;/p&gt;




&lt;p&gt;&lt;code&gt;FROM openjdk:11&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;Purpose:&lt;/em&gt;
This specifies the base image for your container.

&lt;ul&gt;
&lt;li&gt;  openjdk:11 is a lightweight image containing the Java Development Kit (JDK) for Java 11.&lt;/li&gt;
&lt;li&gt;  It provides everything needed to compile and run Java applications.&lt;/li&gt;
&lt;li&gt;  Using a specific version (11) ensures consistency and avoids issues from version mismatches.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;p&gt;&lt;code&gt;COPY . /app&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;Purpose:&lt;/em&gt;
This copies &lt;em&gt;all files&lt;/em&gt; from your current working directory on the host machine to the /app directory inside the container.

&lt;ul&gt;
&lt;li&gt;  For example, this will include your Java source files (Main.java) and any other files needed to run your application.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;p&gt;&lt;code&gt;WORKDIR /app&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;Purpose:&lt;/em&gt;
This sets the working directory inside the container to /app.

&lt;ul&gt;
&lt;li&gt;  All subsequent commands (like RUN or CMD) will execute relative to this directory.&lt;/li&gt;
&lt;li&gt;  It ensures your application files are in the right location before compilation or execution.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;p&gt;&lt;code&gt;RUN javac Main.java&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;Purpose:&lt;/em&gt;
This compiles your Main.java file using the javac (Java Compiler) command inside the container.

&lt;ul&gt;
&lt;li&gt;  The javac command generates the bytecode .class file (e.g., Main.class), which is necessary to run the Java application.&lt;/li&gt;
&lt;li&gt;  If your application has multiple Java files or dependencies, make sure they are all copied and accessible for compilation.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;p&gt;&lt;code&gt;CMD ["java", "Main"]&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;em&gt;Purpose:&lt;/em&gt;
This specifies the command the container should run when it starts.

&lt;ul&gt;
&lt;li&gt;  java Main executes your compiled Java program (Main.class).&lt;/li&gt;
&lt;li&gt;  CMD runs the application in the foreground, ensuring the container remains active while the application runs.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;p&gt;After building and running the container, your Java application will execute and output results to the terminal (or wherever your app is programmed to send them).&lt;/p&gt;

&lt;h3&gt;
  
  
  Build and Run
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Build the image:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker build -t my-java-app .
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run the container:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run my-java-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Output:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You should see:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Hello, World!!&lt;/code&gt;&lt;/p&gt;

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

&lt;p&gt;I hope this blog helps y'all out in passing this lab exam. This was genuinely fun to write and solve , not sure what your faculty did the entire semester if he/she didn't share this material. While all of this is available online and probably written and explained better, I tried my best in explaining it in my terms and how I would solve all of them.&lt;/p&gt;

&lt;p&gt;Then again, your lab systems will have internet. Without internet, you can't run any of the above programs anyways? So yes , its easy to google up the steps or look up this handout during the exam.&lt;/p&gt;

&lt;p&gt;Feeling grattitude? I accept payments in the form of &lt;em&gt;cadbury fuse&lt;/em&gt; , &lt;em&gt;mango lassi&lt;/em&gt; and ocassionally *ganne ka juice. Yes, this is part of my work at Vance and as a devops engineer. Yes, this is a very very smol drop in the ocean of devops and things get complicated really quickly with monitoring and kubernetes and yamls etc. Yes I need to touch some grass and yes, all of you reading are *profoundly welcome &amp;lt;3&lt;/p&gt;

&lt;p&gt;Thanks for reading :))&lt;/p&gt;

</description>
      <category>devops</category>
      <category>docker</category>
      <category>jenkins</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Why we Built a Mini-Language for a Golang Hackathon</title>
      <dc:creator>Akash Singh</dc:creator>
      <pubDate>Fri, 29 Nov 2024 07:33:01 +0000</pubDate>
      <link>https://forem.com/skysingh04/why-we-built-a-mini-language-for-a-golang-hackathon-42a3</link>
      <guid>https://forem.com/skysingh04/why-we-built-a-mini-language-for-a-golang-hackathon-42a3</guid>
      <description>&lt;h2&gt;
  
  
  A Hackathon, Again?
&lt;/h2&gt;

&lt;p&gt;At this point, I have been to &lt;em&gt;9 hackathons&lt;/em&gt;, one of them being an &lt;em&gt;international one&lt;/em&gt;, even winning at &lt;strong&gt;4&lt;/strong&gt; of them. Then again, when my juniors &lt;a href="https://www.linkedin.com/in/dhruvpuri-slashex/" rel="noopener noreferrer"&gt;Dhruv&lt;/a&gt; and &lt;a href="https://www.linkedin.com/in/tusharmohapatra07/" rel="noopener noreferrer"&gt;Tushar&lt;/a&gt; told me about a Golang Specific hackathon, I dragged &lt;a href="https://www.linkedin.com/in/harsh-joshi-82b83530b/" rel="noopener noreferrer"&gt;Harsh&lt;/a&gt; along with us because why not. And not just Harsh, I dragged along 40+ people from our team &lt;a href="https://www.linkedin.com/company/point-blank-d" rel="noopener noreferrer"&gt;Point Blank&lt;/a&gt;, which ended up making the hackathon our own internal competition haha.&lt;/p&gt;

&lt;p&gt;All of us in our team &lt;strong&gt;GoGoingGone&lt;/strong&gt; (lmao) had good experience working with Golang, But we wanted to do more than just build another tool. We wanted to innovate. That’s when the idea struck—&lt;strong&gt;let's build a mini-language&lt;/strong&gt; to define dynamic, configurable data pipelines.&lt;/p&gt;

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

&lt;p&gt;I am Akash Singh, a third year engineering student and Open Source Contributor from Bangalore.&lt;br&gt;
Here is my &lt;a href="https://www.linkedin.com/in/skysingh04/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, &lt;a href="https://github.com/SkySingh04" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; and &lt;a href="https://x.com/SkySingh04" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&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%2F4eayocft44kkbwoqpc8z.JPG" 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%2F4eayocft44kkbwoqpc8z.JPG" alt="Sky Singh" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I go by the name SkySingh04 online.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Introducing &lt;strong&gt;Fractal&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Fractal started as a data processing tool for seamless migration from legacy systems (like SQL databases and CSV files) to modern platforms such as &lt;strong&gt;MongoDB&lt;/strong&gt; or &lt;strong&gt;AWS S3&lt;/strong&gt;. But we wanted more than just another ETL tool. The idea was to make it &lt;strong&gt;highly flexible and user-friendly&lt;/strong&gt;, allowing users to define &lt;strong&gt;validation&lt;/strong&gt; and &lt;strong&gt;transformation rules&lt;/strong&gt; with a simple, declarative syntax—a mini-language within the tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a Mini-Language?
&lt;/h2&gt;

&lt;p&gt;We observed that most tools in the data pipeline space rely on rigid configurations or custom scripts. This approach often requires significant programming expertise, which limits accessibility for non-developers. A declarative mini-language provides:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Simplicity&lt;/strong&gt;: Users define rules in an intuitive, human-readable format.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility&lt;/strong&gt;: It accommodates a wide range of use cases, from basic validations to complex transformations.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt;: The mini-language can evolve as new requirements arise.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This mini-language wasn’t about reinventing the wheel—it was about providing an abstraction to streamline data transformations and validations.&lt;/p&gt;

&lt;p&gt;When this is combined with a simple yaml file configuration, we thought we hit the mark of making a easy to configure data pipeline that can process data from one source to another on scale.&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%2F866zlhwdw951e4c89420.jpg" 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%2F866zlhwdw951e4c89420.jpg" alt="YAML FILE" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Core: Validation and Transformation Syntax
&lt;/h2&gt;

&lt;p&gt;We designed the syntax to be simple yet expressive, focusing on two primary operations:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Validation Rules&lt;/strong&gt;
These ensure incoming data meets specific quality standards before further processing. For example:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   FIELD("age") TYPE(INT) RANGE(18, 65)
   FIELD("email") MATCHES(EMAIL_REGEX)
   FIELD("status") IN ("active", "inactive")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Transformation Rules&lt;/strong&gt;
These enable data enrichment or restructuring. For example:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   RENAME("old_field", "new_field")
   MAP("status", {"0": "inactive", "1": "active"})
   ADD_FIELD("processed_at", CURRENT_TIME())
   IF FIELD("age") &amp;gt; 50 THEN ADD_FIELD("senior_discount", TRUE)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This abstraction allowed users to process diverse datasets with minimal effort, enhancing productivity and reducing complexity.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In the middle of figuring out how to make the lexer and parser of this language, the team at &lt;a href="https://www.linkedin.com/company/gofr-dev/" rel="noopener noreferrer"&gt;GoFr.dev&lt;/a&gt; took us all upstairs for a stress busting session, which was full of late night sharayis and jam sessions!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Building Fractal at the Hackathon
&lt;/h2&gt;

&lt;p&gt;The hackathon wasn’t just about creating the mini-language. We also had to build the surrounding infrastructure, ensuring Fractal was:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Extensible&lt;/strong&gt;: Supporting multiple input/output formats like JSON, CSV, SQL databases, and message queues.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configurable&lt;/strong&gt;: YAML-based configuration for defining pipeline workflows, integrating the mini-language seamlessly.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Robust&lt;/strong&gt;: Handling errors gracefully with options like &lt;code&gt;LOG_AND_CONTINUE&lt;/code&gt; or &lt;code&gt;STOP&lt;/code&gt;.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We divided the work into four modules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mini-Language Implementation&lt;/strong&gt;: Designing the lexer and parser to interpret the custom syntax.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Integrations&lt;/strong&gt;: Adding support for common data sources and destinations.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pipeline Engine&lt;/strong&gt;: Orchestrating validation, transformation, and error handling.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CLI Interface&lt;/strong&gt;: Providing a simple interface for defining and running pipelines.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Challenges We Faced
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Designing the Syntax&lt;/strong&gt;
Striking a balance between simplicity and flexibility was a challenge. We iterated multiple times to finalize the syntax.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Building the Parser&lt;/strong&gt;
Implementing a custom lexer and parser in Golang was time-consuming but rewarding.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-Time Feedback&lt;/strong&gt;
Ensuring that the mini-language provided meaningful error messages to guide users was critical for usability.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time Constraints&lt;/strong&gt;
Building a tool of this scale in a hackathon setting required precise planning and seamless coordination.
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  And what happened after that?
&lt;/h2&gt;

&lt;p&gt;Despite our strong showing at the GO for GOFR hackathon, we faced a critical challenge during the final evaluation. The judges requested a live demonstration in addition to our recorded demo, and unfortunately, we encountered an unexpected bug in our parser logic during the live run. Given the complexity of building a robust custom parser within just 24 hours, it was an ambitious feature to develop, and while our recorded demo showcased its functionality, achieving 100% accuracy under time constraints proved difficult. This hiccup ultimately cost us the top prize. However, our efforts were still highly regarded, and our team's clear vision and compelling delivery earned us the honor of "Best Pitch," highlighting our potential and ingenuity.&lt;/p&gt;
&lt;h2&gt;
  
  
  So Hackathons huh?
&lt;/h2&gt;

&lt;p&gt;Hackathons are often about pushing boundaries and exploring uncharted territories. Fractal was our attempt to redefine how data processing tools can work—by making them accessible, modular, and developer-friendly.  &lt;/p&gt;

&lt;p&gt;I couldn't have asked for a more likeminded set of people to work with me on this, absolute best and hardworking teammates without a shadow of a doubt. Looking forward to what brings me to my next hackathon, dare I say, A RUST based hackathon? xD&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Check out Fractal on GitHub&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/SkySingh04" rel="noopener noreferrer"&gt;
        SkySingh04
      &lt;/a&gt; / &lt;a href="https://github.com/SkySingh04/Fractal" rel="noopener noreferrer"&gt;
        Fractal
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A flexible, configurable data processing tool
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="MD"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Fractal&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Fractal&lt;/strong&gt; is a flexible, configurable data processing tool built with &lt;strong&gt;GoFr&lt;/strong&gt; and &lt;strong&gt;Golang&lt;/strong&gt;. Fractal is designed to handle data ingestion from multiple sources, apply powerful transformations and validations, and deliver output to a wide range of destinations. With Fractal, you can automate complex data workflows without needing to manage low-level details
Here's the documentation for setting up a new integration in your project:&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;&lt;strong&gt;Custom Syntax Documentation for Validation and Transformation Rules&lt;/strong&gt;&lt;/h3&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;&lt;strong&gt;1. Overview&lt;/strong&gt;&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;The custom syntax enables users to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Validate incoming data to ensure it meets predefined conditions.&lt;/li&gt;
&lt;li&gt;Transform data fields to fit desired formats, structures, or requirements.&lt;/li&gt;
&lt;li&gt;Define flexible error-handling strategies for data processing pipelines.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Rules can be written for any data source or destination, such as &lt;strong&gt;JSON&lt;/strong&gt;, &lt;strong&gt;YAML&lt;/strong&gt;, &lt;strong&gt;CSV&lt;/strong&gt;, &lt;strong&gt;SQL Databases&lt;/strong&gt;, &lt;strong&gt;Message Brokers&lt;/strong&gt;, or &lt;strong&gt;Cloud Services&lt;/strong&gt;.&lt;/p&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;&lt;strong&gt;2. Validation Rules&lt;/strong&gt;&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;Validation rules ensure that data meets specific quality and integrity requirements.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;…&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/SkySingh04/Fractal" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;
Pitch Deck : &lt;a href="https://drive.google.com/file/d/1NqRfXqPrgXbKFL8mdKkuovxcaaEBT12S/view?usp=sharing" rel="noopener noreferrer"&gt;Drive Link&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Or Try it Yourself and let us know what do you think!&lt;/strong&gt;&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%2Fr95jo37sqp0wgtf7u4s8.jpg" 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%2Fr95jo37sqp0wgtf7u4s8.jpg" alt="FRACTAL QR" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>codenewbie</category>
      <category>backend</category>
      <category>database</category>
    </item>
    <item>
      <title>How Talking to a College Senior taught me Devops/Gitops</title>
      <dc:creator>Akash Singh</dc:creator>
      <pubDate>Fri, 22 Nov 2024 17:20:10 +0000</pubDate>
      <link>https://forem.com/skysingh04/how-talking-to-a-college-senior-taught-me-devopsgitops-7fp</link>
      <guid>https://forem.com/skysingh04/how-talking-to-a-college-senior-taught-me-devopsgitops-7fp</guid>
      <description>&lt;h1&gt;
  
  
  The Story
&lt;/h1&gt;

&lt;p&gt;I love going to hackathons. Not just for participating, but for meeting new people and seeing what people are building in general. This year in May, I went to a hackathon &lt;strong&gt;Aventus&lt;/strong&gt;, not for participating but for meeting some seniors and peers. While there, I met &lt;a href="https://www.linkedin.com/in/rishabhlakhotia/" rel="noopener noreferrer"&gt;Rishabh Lakhotia&lt;/a&gt;, an alumnus of &lt;a href="https://www.linkedin.com/company/point-blank-d/" rel="noopener noreferrer"&gt;Point Blank&lt;/a&gt; , who told me of an intern opening at his company &lt;a href="https://www.linkedin.com/company/vanceapp/posts/?feedView=all" rel="noopener noreferrer"&gt;Vance&lt;/a&gt;. Now I personally always had an interest for Devops, but when I talked to him, I was bombarded with words like GITOPS and Infrastructure As Code and Terraform! The only course of action was to figure out what all of this meant so that I could have a chance clearing the interview. The best way I figured I could stand out was implementing all of what I learnt in my existing project. This blog post will break down the essentials of GitOps and share insights from my implementation process.&lt;/p&gt;

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

&lt;p&gt;I am Akash Singh, a third year engineering student and Open Source Contributor from Bangalore.&lt;br&gt;
Here is my &lt;a href="https://www.linkedin.com/in/skysingh04/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, &lt;a href="https://github.com/SkySingh04" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; and &lt;a href="https://x.com/SkySingh04" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&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%2F4eayocft44kkbwoqpc8z.JPG" 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%2F4eayocft44kkbwoqpc8z.JPG" alt="Sky Singh" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I go by the name SkySingh04 online.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  What is GitOps?
&lt;/h2&gt;

&lt;p&gt;At its core, GitOps brings Git’s version control capabilities to the world of DevOps. By treating Git as a "single source of truth," GitOps manages both application code and Infrastructure as Code (IaC) in separate Git repositories. This setup provides several benefits:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Easy Rollback:&lt;/strong&gt; Git history enables version tracking, allowing teams to revert to a previous state in seconds if something goes wrong.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Increased Security:&lt;/strong&gt; By controlling code changes through pull requests and Git’s in-built security features, GitOps enhances deployment security.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Complete Automation:&lt;/strong&gt; With automated CI/CD pipelines, deployment becomes a smooth, consistent process where each code push triggers relevant updates and builds.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In GitOps, the desired state of the infrastructure and applications is stored in Git. Any changes to this state, whether application code updates or infrastructure configurations, are tracked, reviewed, and managed through pull requests. This approach reduces manual intervention and allows teams to deliver faster and more reliable updates.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;While learning about Gitops, I found this extremely helpful video &lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/f5EpcWp0THw"&gt;
&lt;/iframe&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Implementing GitOps in HaalSamachar
&lt;/h2&gt;

&lt;p&gt;Okay now I understood what Gitops is, how exactly do I implement it? Well, lets break it down :&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Separating Application and Infrastructure Code
&lt;/h3&gt;

&lt;p&gt;To fully leverage GitOps principles, I separated &lt;strong&gt;application&lt;/strong&gt; and &lt;strong&gt;infrastructure&lt;/strong&gt; code into two distinct Git repositories. This organizational shift made it easier to manage each part independently while aligning with GitOps best practices. For HaalSamachar, this meant dedicating one repository to the application codebase and another to the Infrastructure as Code (IaC) scripts.&lt;/p&gt;

&lt;p&gt;The benefit of this separation became apparent when making infrastructure updates. Now, I could manage infrastructure changes without interfering with the main application codebase, reducing complexity and providing a more modular approach to handling deployments and updates.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Here is the GitOps Application Repository&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/SkySingh04" rel="noopener noreferrer"&gt;
        SkySingh04
      &lt;/a&gt; / &lt;a href="https://github.com/SkySingh04/Haalsamachar-app" rel="noopener noreferrer"&gt;
        Haalsamachar-app
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Application Repository for HaalSamachar consisting of Backend Microservices built with GoLang including a GraphQL API built using gqlgen and four REST APIs built using Gin and frontend built with NextJs+TypeScript with PostgreSQL powered database, containerized using Docker. 
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;HaalSamachar Application Repository : Consists of Backend Microservices built with GoLang including a GraphQL API built using gqlgen and four REST APIs built using Gin and frontend built with NextJs+TypeScript with PostgreSQL powered database, containerized using Docker using Dockerfiles and CI/CD pipeline configurations.&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;
&lt;a href="https://github.com/Akash-Singh04/haalsamachar-infra" rel="noopener noreferrer"&gt;HaalSamachar Infrastructure Repository&lt;/a&gt; : Contains Terraform scripts, Kubernetes manifests, and GitOps configurations for Haalsamachar App.&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GraphQL API:&lt;/strong&gt; Utilizing gqlgen for creating a GraphQL server to efficiently query and manipulate data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;REST APIs:&lt;/strong&gt; Three REST APIs are built using Gin for handling various functionalities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker &amp;amp; Kubernetes:&lt;/strong&gt; Containerized using Docker.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Next.js with SSR:&lt;/strong&gt; Frontend developed using Next.js for server-side rendering (SSR) along with TypeScript and Tailwind CSS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PostgreSQL:&lt;/strong&gt; Utilized as the database to store and manage data efficiently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Firebase Auth:&lt;/strong&gt; Integrated Firebase authentication for user authentication and authorization.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Continuous Integration/Continuous Deployment (CI/CD)&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;CI/CD pipelines automate the process of testing and deploying code changes. HaalSamachar utilizes CI/CD practices…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/SkySingh04/Haalsamachar-app" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;And Here is the GitOps Infrastructure Repository&lt;/p&gt;
&lt;/blockquote&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/SkySingh04" rel="noopener noreferrer"&gt;
        SkySingh04
      &lt;/a&gt; / &lt;a href="https://github.com/SkySingh04/Haalsamachar-infra" rel="noopener noreferrer"&gt;
        Haalsamachar-infra
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Haalsamachar IAC : Contains  Terraform scripts, Kubernetes manifests, and GitOps configurations for Haalsamachar App
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;HaalSamachar Infrastructure Repository : The Haalsamachar App's infrastructure is managed through an Infrastructure as Code (IaC) approach, incorporating Terraform scripts, Kubernetes manifests, and GitOps configurations. This ensures automated, scalable, and consistent deployment of resources.&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;
&lt;a href="https://github.com/Akash-Singh04/haalsamachar-app" rel="noopener noreferrer"&gt;HaalSamachar Application Repository&lt;/a&gt; : Consists of Backend Microservices built with GoLang including a GraphQL API built using gqlgen and four REST APIs built using Gin and frontend built with NextJs+TypeScript with PostgreSQL powered database, containerized using Docker using Dockerfiles and CI/CD pipeline configurations.&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Setting Up Kubernetes Cluster&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;The kubernetes deployment configuration yaml files are located in &lt;code&gt;/deployment&lt;/code&gt; directory. These can be modified to scale the number of pods and other configurations as per requirements.&lt;/p&gt;
&lt;p&gt;To deploy HaalSamachar using Kubernetes, follow these steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Install Kubernetes:&lt;/strong&gt; Set up a Kubernetes cluster on your preferred cloud provider or locally using Minikube.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Apply Manifests:&lt;/strong&gt; Use &lt;code&gt;kubectl apply /deployments&lt;/code&gt; command to apply the Kubernetes manifests and deploy the HaalSamachar application to…&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/SkySingh04/Haalsamachar-infra" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  Step 2: Leveraging AWS Services – ECR and ECS
&lt;/h3&gt;

&lt;p&gt;Now two other things that I gathered from my conversation with Rishabh Bhaiya was they are using AWS ECR and AWS ECS. I had no idea what these were but oh well, time to implement them.&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%2Ftf49zfi31sh97ca9sxis.jpg" 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%2Ftf49zfi31sh97ca9sxis.jpg" alt=" " width="800" height="324"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In a nutshell : &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ECR&lt;/strong&gt; serves as a private repository where Docker images are stored, ensuring each build is securely stored and readily available for deployment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ECS&lt;/strong&gt; handles the orchestration and management of these containers, simplifying the deployment and scaling of containers across a fleet of machines.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Okay, now I need to figure out how to deploy HaalSamachar’s application in a containerized environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Setting Up ECR and ECS for HaalSamachar
&lt;/h3&gt;

&lt;p&gt;Once I got the basics of &lt;strong&gt;ECR (Elastic Container Registry)&lt;/strong&gt; and &lt;strong&gt;ECS (Elastic Container Service)&lt;/strong&gt; down, I moved on to implement them in HaalSamachar. Here’s how it went down:&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Configuring ECR&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;First, I needed a private, secure location to store the Docker images of HaalSamachar. ECR was perfect for this, as it integrates seamlessly with other AWS services and provides a safe, centralized storage for my Docker images.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create the ECR Repository:&lt;/strong&gt; Using the AWS Management Console, I set up a new repository in ECR, allowing it to hold the Docker images for each deployment version of HaalSamachar.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set Up Permissions:&lt;/strong&gt; Next, I configured permissions to allow ECS (Elastic Container Service) to pull images from ECR whenever needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Push Docker Images to ECR:&lt;/strong&gt; Every time I update the application, I generate a new Docker image and push it to ECR using AWS CLI. This versioning lets me maintain consistency and track changes efficiently.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Deploying with ECS&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;With the Docker images stored in ECR, I moved on to ECS, AWS’s container orchestration service. Here’s how I leveraged ECS to deploy and manage HaalSamachar:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Task Definition:&lt;/strong&gt; ECS required a task definition that specified how my application should run in a containerized environment. I defined details like container image source (pointing to ECR), memory, CPU requirements, and port mappings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Service Setup:&lt;/strong&gt; I created an ECS service to manage the deployment and scaling of my container. The service enables ECS to monitor the health of containers and replace any failing instances automatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cluster and Deployment:&lt;/strong&gt; Finally, I launched the service within an ECS cluster, which facilitated the management of container instances on AWS infrastructure.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By setting up ECS, I didn’t need to worry about manually handling containers. AWS took care of the orchestration, and ECS's auto-scaling capabilities ensured that the application could handle varying traffic loads without manual intervention.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Automating Deployments with GitHub Actions
&lt;/h3&gt;

&lt;p&gt;Once the infrastructure was in place, I needed a way to automate deployments. Enter &lt;strong&gt;GitHub Actions&lt;/strong&gt;, a CI/CD tool that was critical in implementing GitOps for HaalSamachar. As it turns out, this was also how Vance handled their workflow.&lt;/p&gt;

&lt;p&gt;I set up a workflow in GitHub Actions with the following stages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Build Stage:&lt;/strong&gt; Every time I pushed changes to the main branch, the workflow would kick off a build. This stage created a Docker image of HaalSamachar from the latest code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Push to ECR:&lt;/strong&gt; After the Docker image was built, it was automatically pushed to the ECR repository. This step ensured that the latest code changes were available in the image repository for deployment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deploy on ECS:&lt;/strong&gt; The final stage involved updating the ECS service with the new Docker image. GitHub Actions triggered the deployment on ECS, which fetched the latest image from ECR and deployed it seamlessly.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This workflow significantly streamlined my deployment process. Each push to the main branch automatically triggered a full deployment pipeline, reducing the chance for human error and increasing efficiency.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's the point tho?
&lt;/h3&gt;

&lt;p&gt;My conversation with Rishabh bhaiya was a turning point. Before that hackathon, I only had a high-level curiosity about DevOps. Concepts like &lt;strong&gt;GitOps&lt;/strong&gt;, &lt;strong&gt;IaC (Infrastructure as Code)&lt;/strong&gt;, and &lt;strong&gt;Terraform&lt;/strong&gt; felt out of reach, almost like advanced topics for “real” engineers. But Rishabh’s words inspired me to dive in, to experiment with these concepts hands-on and push my project, HaalSamachar, to new heights.&lt;/p&gt;

&lt;p&gt;After that initial chat, I studied, broke down, and pieced together everything I could about GitOps and DevOps fundamentals. I watched tutorials, read documentation, and learned by building. Even though I didn’t land the internship at Vance, the journey to prepare for that opportunity reshaped my perspective on software engineering. It wasn’t about the end goal of landing a position but rather the growth I experienced by stretching myself beyond my comfort zone.&lt;/p&gt;

&lt;p&gt;Through this project, I realized that HaalSamachar, while perhaps not my most sophisticated work, holds special meaning. It's a project where I could test my understanding of GitOps and learn AWS services like ECR and ECS from scratch. Watching it come together made the late nights of debugging, building Docker images, and learning CI/CD feel incredibly rewarding. In the end, HaalSamachar taught me that you don’t have to wait for the “perfect” project or opportunity to dive into new tech. Just start where you are, learn, and build something—no matter how small, it will move you forward.&lt;/p&gt;

&lt;p&gt;As I look to future projects, HaalSamachar will always hold a unique place in my journey. It’s not just a news aggregation tool; it’s the project that introduced me to GitOps and sparked my journey into the world of DevOps. And that’s thanks to a simple conversation with a senior who was willing to share what he knew.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>gitops</category>
      <category>infrastructureascode</category>
      <category>terraform</category>
    </item>
    <item>
      <title>My CloudSEK Internship Experience</title>
      <dc:creator>Akash Singh</dc:creator>
      <pubDate>Mon, 11 Nov 2024 12:59:59 +0000</pubDate>
      <link>https://forem.com/skysingh04/my-cloudsek-internship-experience-4oh2</link>
      <guid>https://forem.com/skysingh04/my-cloudsek-internship-experience-4oh2</guid>
      <description>&lt;p&gt;This article is about my internship at &lt;a href="https://www.linkedin.com/company/cloudsek/posts/?feedView=all" rel="noopener noreferrer"&gt;CloudSEK&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;CloudSEK is a &lt;u&gt;cybersecurity company &lt;/u&gt; that uses artificial intelligence and machine learning to identify and manage digital threats!&lt;/p&gt;

&lt;p&gt;A lot of my seniors at &lt;a href="https://www.linkedin.com/company/point-blank-d/posts/?feedView=all" rel="noopener noreferrer"&gt;Point Blank&lt;/a&gt; were working / had worked at CloudSEK. So, when I got to know CloudSEK is looking for interns &lt;em&gt;I HAD to apply&lt;/em&gt;! In this blog post, I will describe the application process, the interview process, and my experience working at this company.&lt;/p&gt;

&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;I am Akash Singh, a third year engineering student and Open Source Contributor from Bangalore.&lt;br&gt;
Here is my &lt;a href="https://www.linkedin.com/in/skysingh04/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, &lt;a href="https://github.com/SkySingh04" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; and &lt;a href="https://x.com/SkySingh04" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&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%2F4eayocft44kkbwoqpc8z.JPG" 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%2F4eayocft44kkbwoqpc8z.JPG" alt="Sky Singh" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I go by the name SkySingh04 online.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Selection Process
&lt;/h2&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%2Fy3vyfz6bhuhw7a1x9tgk.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%2Fy3vyfz6bhuhw7a1x9tgk.png" alt=" " width="800" height="284"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This was probably one of the most in-depth recruitment process I had ever been a part of.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;u&gt;Application&lt;/u&gt; :&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I had initially found the open intern position on LinkedIn. After applying there, I had asked my seniors at Point Blank to provide a referral for the same. I ended up working in the same Pod (team) as my senior &lt;a href="https://www.linkedin.com/in/aditya-b-n-7a39b459/" rel="noopener noreferrer"&gt;Aditya&lt;/a&gt;. Shortly after which, I received a confirmation email and my interview was scheduled.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;u&gt;HR Round&lt;/u&gt; :&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This round was conducted to ensure I will be able to provide the necessary commitment of 3 months to the internship, along with general discussions about my past internships and experience and why I wanted to work at CloudSEK.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;u&gt;Interview Round 1 &lt;/u&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This round was headed by my team leader. We went over my resume, my past experiences with Golang including my Google Summer of code project. This was followed by some system design questions and then DBMS / SQL fundamentals with a database design problem as well.&lt;/p&gt;

&lt;p&gt;If you have a good grasp of CS Fundamentals and Database fundamentals, this round should be easy enough. You will have a positive experience if you are confident in the skills you've listed on your resume. Be thorough with your Projects.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;u&gt; Interview Round 2 &lt;/u&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This round was taken by the tech lead of Core Platform Engineering team. The thing that gave me an advantage in this round was my &lt;a href="https://github.com/skysingh04/DNS-Server-Rust" rel="noopener noreferrer"&gt;DNS Server Project&lt;br&gt;
&lt;/a&gt; which was written in &lt;strong&gt;RUST&lt;/strong&gt; . The interviewer took keen interest in my project and we discussed it for half an hour. This was then proceeded by a System Design question, which was to be designed and implemented in &lt;strong&gt;GO&lt;/strong&gt;.This really had me sweating and I am actually surprised I was able to implement it.&lt;/p&gt;

&lt;p&gt;If you have interesting projects and are thorough with the implementation and various nuances of it, you are good to go! Stay confident and try to solve the system design question while considering all edge cases. The company is okay if you google during the interview. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SELECTED! 🎉&lt;/li&gt;
&lt;/ul&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%2Fc1gp4s6chs8qcaaj0x25.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%2Fc1gp4s6chs8qcaaj0x25.png" alt=" " width="800" height="479"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The thing I realised about CloudSEK was, whatever questions / topics they had covered during the interviews, they had direct application during the job. This was a breathe of fresh air from all the leetcode based hiring (xD)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  My Experience
&lt;/h2&gt;

&lt;p&gt;Working as a Backend Engineer intern at CloudSEK was a transformative experience where I gained hands-on exposure to advanced development practices, &lt;em&gt;cloud services&lt;/em&gt;, and &lt;em&gt;CI/CD pipeline management&lt;/em&gt;. My primary focus areas included maintaining and developing microservices for the &lt;em&gt;CloudSEK Community Server&lt;/em&gt;, which was entirely written in GO. I tackled various tasks ranging from writing controllers to exploring &lt;strong&gt;OpenTelemetry&lt;/strong&gt; for monitoring, adding both breadth and depth to my skillset, along with designing Databases using POSTGRES and MongoDB (yes now the interview questions make sense). &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I worked primarily from office during my internship. The office was always full of snacks, unlimited caffeine and hardworking individuals alike.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I explored various monitoring and observability tools, such as &lt;u&gt;Grafana&lt;/u&gt;, &lt;u&gt;Loki&lt;/u&gt;, and &lt;u&gt;OpenTelemetry&lt;/u&gt;, to set up and analyze metrics effectively. This deep dive helped me understand the importance of real-time insights for backend health, helping us quickly identify bottlenecks and optimize resource allocation. Additionally, I learned so much about &lt;u&gt;Load testing&lt;/u&gt;, writing &lt;u&gt;Integration and Unit tests&lt;/u&gt;, and fell more and more &lt;strong&gt;in love with Golang&lt;/strong&gt;❤️.&lt;/p&gt;

&lt;p&gt;I was also exposed to &lt;em&gt;Gitops and secret managements&lt;/em&gt;, writing scalable microservices and monorepos, generating documentation using &lt;strong&gt;Swagger&lt;/strong&gt; and deploying my services using &lt;strong&gt;Kubernetes&lt;/strong&gt;! The fact that I was given the full liberty to design, implement and deploy my own services meant that I had to take care of everything from &lt;em&gt;writing tests&lt;/em&gt; to building the CI/CD pipeline to deploying the changes using &lt;strong&gt;ArgoCD&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;CloudSEK is a &lt;u&gt;RFC-First company&lt;/u&gt;. What this means is, before you actually start coding, you are supposed to write a &lt;em&gt;Request for Change (RFC) document&lt;/em&gt; for whatever changes you are introducing / service you are building. I had to write many RFC's while working on the &lt;em&gt;Cloudsek Community Server&lt;/em&gt; , which used to go through multiple rounds of reviews. This documentation helped align our team on design decisions and ensured clarity on the objectives, benefits, and technical details of upcoming features. Completing the RFCs taught me the value of clear, technical communication in project planning.&lt;/p&gt;

&lt;p&gt;Along with all of this learning, I was also exposed to so many &lt;em&gt;AWS&lt;/em&gt; tools such as &lt;strong&gt;Simple Storage Service&lt;/strong&gt; (S3), &lt;strong&gt;Simple Queuing Service&lt;/strong&gt; (SQS) along with tools like &lt;strong&gt;Kafka&lt;/strong&gt;, &lt;strong&gt;Redis&lt;/strong&gt; etc. Oh and did I mention, you cannot survive a day in CloudSEK without Docker? Haha, yes I worked with lots of Docker and CI pipelines during my internship and it was super fun!&lt;/p&gt;

&lt;h2&gt;
  
  
  My Introduction To Cybersecurity
&lt;/h2&gt;

&lt;p&gt;One of the highlights of my internship at CloudSEK was my first real exposure to cybersecurity. I not only had the chance to work on projects directly impacting cybersecurity solutions, but I also completed an internal course, &lt;em&gt;CloudSEK External Threat Monitoring Solutions&lt;/em&gt;, which deepened my understanding of the field. This course provided valuable insights into identifying and managing digital threats, leveraging tools and techniques used by cybersecurity professionals to protect organizations against external attacks.&lt;/p&gt;

&lt;p&gt;The course wasn’t just theoretical—it included a Capture The Flag (CTF) challenge that put my problem-solving skills to the test. Engaging with real-world cybersecurity scenarios and tackling CTF challenges gave me a hands-on experience that solidified my foundational knowledge in cybersecurity.&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%2Ffg35nqxf0xgh2rzcy5z0.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%2Ffg35nqxf0xgh2rzcy5z0.png" alt=" " width="800" height="562"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Even though cybersecurity was not my field of interest, this exposure only increased my field of knowledge. Thanks to the CPE team for making me do this!&lt;/p&gt;

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

&lt;p&gt;CloudSEK is an amazing place to be a developer. I’m incredibly grateful for the support and camaraderie of my team. Each senior I worked with brought a wealth of knowledge and was always eager to share, making every project not only a task but a learning opportunity. From brainstorming sessions to coding sprints, the team’s dedication and passion for cybersecurity were infectious. &lt;/p&gt;

&lt;p&gt;The office itself was a constant source of motivation—with an endless supply of coffee, snacks, and a culture that genuinely valued hard work and curiosity. Truly one of the best offices in Bangalore to work at!&lt;/p&gt;

&lt;p&gt;You will learn and grow as the team is open to trying new technologies. They keep on adopting new tools and technologies thus there is always something to learn! I’m excited to take all that I’ve learned here into my future endeavors, carrying with me the invaluable experience of working at a company that’s genuinely making a difference in the digital landscape. &lt;/p&gt;

&lt;p&gt;Thanks for reading my article :)&lt;/p&gt;

</description>
      <category>codenewbie</category>
      <category>career</category>
      <category>go</category>
      <category>cybersecurity</category>
    </item>
    <item>
      <title>Hacktoberfest : The right way to do open source</title>
      <dc:creator>Akash Singh</dc:creator>
      <pubDate>Sun, 03 Nov 2024 22:56:12 +0000</pubDate>
      <link>https://forem.com/skysingh04/hacktoberfest-the-right-way-to-do-open-source-4lcp</link>
      <guid>https://forem.com/skysingh04/hacktoberfest-the-right-way-to-do-open-source-4lcp</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest"&gt;2024 Hacktoberfest Writing challenge&lt;/a&gt;: Contributor Experience&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When October began, Me and some seniors at our club &lt;a href="https://www.instagram.com/pointblank_dsce/" rel="noopener noreferrer"&gt;Point Blank&lt;/a&gt; were wondering how we can get the new and existing members of our club to contribute to Open Source and &lt;strong&gt;Hacktoberfest&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;In this blog I will outline and answer the &lt;em&gt;common doubts&lt;/em&gt; related to open source contributions and how to make &lt;strong&gt;Hacktoberfest&lt;/strong&gt; worth it for not only you, but the community as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;I am Akash Singh, a Backend Developer and Open Source Contributor.&lt;br&gt;
Here is my &lt;a href="https://www.linkedin.com/in/skysingh04/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;, &lt;a href="https://github.com/SkySingh04" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; and &lt;a href="https://x.com/SkySingh04" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;&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%2F4eayocft44kkbwoqpc8z.JPG" 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%2F4eayocft44kkbwoqpc8z.JPG" alt="Sky Singh" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I go by the name SkySingh04 online.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  My Contributions
&lt;/h2&gt;

&lt;p&gt;Before I start explaining and answering the FAQ's, It's important to note how I personally did my Hacktoberfest. I was able to &lt;em&gt;finish all 4 PR's&lt;/em&gt;, and am currently working on 2 more PR's even after **Hacktoberfest **ended.&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%2F5uoy7pqcajcewi1qjicm.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%2F5uoy7pqcajcewi1qjicm.png" alt=" " width="800" height="248"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can check out the Merged PR's here : &lt;a href="https://gist.github.com/SkySingh04/24a17f47f6e6da1b7755a03c94f4afc7" rel="noopener noreferrer"&gt;Github Gist&lt;/a&gt; and read about my contributions here &lt;a href="https://www.linkedin.com/posts/skysingh04_hacktoberfest2024-hacktoberfest-hacktoberfest-activity-7259125611942576128-IKQy?utm_source=social_share_send&amp;amp;utm_medium=member_desktop_web&amp;amp;rcm=ACoAAD57BKMBQzryaT68XVOOZuDcpVBBayHGg1U" rel="noopener noreferrer"&gt;LinkedIn Post&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;As far as I scrolled through &lt;em&gt;LinkedIn&lt;/em&gt;, I realize this is on the lower end of contributions. This is where I have a very strong opinion regarding open source in general : &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Quality Over Quantity&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Is it easy enough to submit &lt;strong&gt;10&lt;/strong&gt; more Readme contributions? Yes, infact a number of repos on Github are made specifically for the purpose of getting the &lt;strong&gt;Hacktoberfest&lt;/strong&gt; badges, with zero / minimum actual code.&lt;/p&gt;

&lt;h2&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%2Fpaad903k46f8swbvmzmp.png" alt=" " width="800" height="188"&gt;
&lt;/h2&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%2F6tzpsnjvfgt3vnatkpt0.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%2F6tzpsnjvfgt3vnatkpt0.png" alt=" " width="800" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now I am aware of the guidelines of Hacktoberfest that encourage both Code and &lt;u&gt;No Code Contributions&lt;/u&gt;. As such, I am &lt;u&gt;not against No Code Contributions&lt;/u&gt; , but I am strongly against low effort contributions, which brings us to one of the most common questions.&lt;/p&gt;

&lt;h2&gt;
  
  
  How To Avoid Low Effort Contributions?
&lt;/h2&gt;

&lt;p&gt;We live in an era of the internet where making a &lt;em&gt;Readme change&lt;/em&gt; is as simple as prompting &lt;em&gt;Chatgpt/LLMs&lt;/em&gt; with the right data and it will literally write the Readme/ Documentation for you. &lt;/p&gt;

&lt;p&gt;As a rule of thumb, if the issue can be solved via a simple prompt to Chatgpt, &lt;u&gt;are you even making a contribution&lt;/u&gt; to open source in the first place?&lt;/p&gt;

&lt;p&gt;Moving a step ahead from open source, how is making such a contribution helping you? Are you learning something new? Are you exploring a new codebase? Chances are, the answer is a &lt;strong&gt;NO&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Circling back to the question, I believe the best kind of contributions are those that not only are on &lt;em&gt;Production Code&lt;/em&gt; and help the maintainers, but also help you learn / explore something new. It maybe a &lt;em&gt;new language&lt;/em&gt; you wanted to try, or a &lt;em&gt;new project&lt;/em&gt; you find interesting. The only rule is to not &lt;u&gt;waste the maintainers time&lt;/u&gt; with low effort questions / contributions.&lt;/p&gt;

&lt;p&gt;My whole agenda of doing Hacktoberfest was to get more comfortable with &lt;strong&gt;RUST&lt;/strong&gt; and I am pretty satisfied with my 3/4 PR's being Rust contributions.&lt;/p&gt;

&lt;h2&gt;
  
  
  How To Find Repositories To Contribute?
&lt;/h2&gt;

&lt;p&gt;I will be sharing the trick I shared with my peers and juniors at &lt;a href="https://www.instagram.com/pointblank_dsce/" rel="noopener noreferrer"&gt;Point Blank&lt;/a&gt;. Lets assume you want to contribute to Rust based projects. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One of the best places to find repos to contribute is the &lt;strong&gt;Github topics&lt;/strong&gt; page &lt;/li&gt;
&lt;/ul&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%2F2km2p576bsyekh3j0878.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%2F2km2p576bsyekh3j0878.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On this page , we can easily sort repos by the language of choice.&lt;/li&gt;
&lt;/ul&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%2Fyn4pwedb5payey74jrfk.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%2Fyn4pwedb5payey74jrfk.png" alt=" " width="446" height="613"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The trick is to &lt;u&gt;sort the repos via recently updated&lt;/u&gt;. This ensures you get repos that are not only active, but are actively looking for contributions!&lt;/li&gt;
&lt;/ul&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%2Fsn9eniprzvw8sxcd8odw.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%2Fsn9eniprzvw8sxcd8odw.png" alt=" " width="800" height="598"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And voila&lt;/strong&gt;! You now have a list of repos to go find issues to contribute to!&lt;/p&gt;

&lt;h2&gt;
  
  
  How To Find Issues to work on?
&lt;/h2&gt;

&lt;p&gt;Now, what happened with a lot of my peers at &lt;a href="https://www.instagram.com/pointblank_dsce/" rel="noopener noreferrer"&gt;Point Blank&lt;/a&gt; (and myself) is that we couldn't find good issues that interest us. And when we did, there was already someone working on it.&lt;/p&gt;

&lt;p&gt;Well of course, one solution is to keep on looking for unassigned issues, another is to ask the maintainers if they have any issues for new contributors.&lt;/p&gt;

&lt;p&gt;What I want to talk about is this third scenario where someone has committed to solving a issue but never does. Such kind of people not only &lt;u&gt;deserve a special place in hell&lt;/u&gt;, but also end up ruining the spirit of open source.&lt;/p&gt;

&lt;p&gt;Lets take &lt;a href="https://github.com/digitalocean/doctl/issues/1584" rel="noopener noreferrer"&gt;this issue in Doctl&lt;/a&gt; for example.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In this issue, a contributor initially expressed interest in working on it, and the maintainer gave them the go-ahead. However, after stating they would "close it by Monday," no progress was made, nor was any PR submitted by the set deadline.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This left the issue open and unresolved, which can be frustrating for the project’s progress, especially when other contributors were interested in solving it but held off in respect of the initial claim.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After the original assignee didn’t follow through, I revisited the issue, ensured that no one was actively working on it, and eventually submitted the PR myself.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&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%2Ftvlbn7g7aqxs9w1ebvqq.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%2Ftvlbn7g7aqxs9w1ebvqq.png" alt=" " width="800" height="528"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ultimately, this demonstrates why maintaining clear communication and respecting deadlines are crucial. Committing to an issue and not following through can block other contributors and delay valuable improvements.&lt;/li&gt;
&lt;/ul&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%2Fp1qeact4sfp9mu47m4yc.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%2Fp1qeact4sfp9mu47m4yc.png" alt=" " width="800" height="271"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Key Takeaway&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;If you claim an issue, make sure you’re committed to completing it or communicate with the maintainers if you’re unable to continue. Open source relies heavily on collaboration and transparency, so leaving others in the dark harms the project and wastes community effort.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Amaze, Now really quickly let's go over some Do's and Don'ts&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Do’s ✅
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Find Projects with Active Maintainers and Open Issues&lt;/strong&gt; ✅&lt;br&gt;
Look for repositories that are recently updated and actively managed. This increases the likelihood that your contribution will be seen, reviewed, and merged.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Choose Quality Over Quantity&lt;/strong&gt; ✅&lt;br&gt;
Focus on meaningful contributions that provide real value. Fix bugs, add features, or improve documentation in ways that truly help the project, rather than just seeking to increase your PR count.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Be Transparent and Communicate&lt;/strong&gt; ✅&lt;br&gt;
If you claim an issue, keep the maintainers informed of your progress. If you can’t complete it, let them know so others can pick it up.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use Open Source to Learn and Explore New Tech&lt;/strong&gt; ✅ &lt;br&gt;
Leverage your contributions to explore new languages or frameworks, and deepen your understanding of existing ones. This approach makes contributions more enriching for both you and the project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ask Questions and Seek Help If Needed&lt;/strong&gt; ✅&lt;br&gt;
If you’re stuck, don’t hesitate to ask maintainers or the community for help. Clear communication shows dedication and fosters collaboration.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Don’ts ❌
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Avoid Low-Effort Contributions&lt;/strong&gt; ❌ &lt;br&gt;
Avoid submitting minor or trivial changes, like typo fixes or formatting updates, unless they are genuinely helpful. Contributions should add value to the project and not clutter the maintainers’ workload.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Don’t Claim Issues You Aren't Committed To Completing&lt;/strong&gt; ❌&lt;br&gt;&lt;br&gt;
Claiming issues without follow-through disrupts progress and blocks other contributors who may be eager to work on them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Refrain from Spammy or Artificial Contributions&lt;/strong&gt; ❌&lt;br&gt;&lt;br&gt;
Resist the temptation to create pull requests on fake or spam repositories just to earn a badge. These actions dilute the purpose of Hacktoberfest and harm the integrity of open source.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Don’t Submit Changes You Haven’t Tested&lt;/strong&gt; ❌&lt;br&gt;&lt;br&gt;
Testing your code before submission ensures that you’re not introducing bugs or issues into the project. Untested code is a disservice to the maintainers and fellow contributors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Avoid Relying Entirely on AI Tools for Contributions&lt;/strong&gt; ❌&lt;br&gt;&lt;br&gt;
While tools like ChatGPT can help with generating documentation or code snippets, ensure that your contributions go beyond automated responses. Genuine contributions involve critical thinking and adaptation specific to the project’s needs.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  So What's the point of this?
&lt;/h2&gt;

&lt;p&gt;Hacktoberfest is an opportunity for all of us to learn something new, build and contribute to software all across the world. Who knows what doors it may open for you? Please don't waste it with spam contributions just for the sake of a badge you get to show on LinkedIn.&lt;/p&gt;

&lt;p&gt;Even more so, don't waste the contributors time with spam PR's and low effort contributions. Contributing to open source is about more than just adding to your GitHub profile. It’s an opportunity to grow.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hacktoberfest</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
