<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Pratik Mahalle</title>
    <description>The latest articles on DEV Community by Pratik Mahalle (@pratikmahalle).</description>
    <link>https://dev.to/pratikmahalle</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%2F1338883%2Ff6df614d-8871-433f-8745-36e3f6d1b2e5.jpg</url>
      <title>DEV Community: Pratik Mahalle</title>
      <link>https://dev.to/pratikmahalle</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pratikmahalle"/>
    <language>en</language>
    <item>
      <title>Ephemeral Environments for Developers: The Missing Layer in Your DevEx Stack</title>
      <dc:creator>Pratik Mahalle</dc:creator>
      <pubDate>Sat, 28 Feb 2026 02:34:29 +0000</pubDate>
      <link>https://dev.to/exemplar/ephemeral-environments-for-developers-the-missing-layer-in-your-devex-stack-5cjj</link>
      <guid>https://dev.to/exemplar/ephemeral-environments-for-developers-the-missing-layer-in-your-devex-stack-5cjj</guid>
      <description>&lt;p&gt;If your team is still sharing a handful of long‑lived “dev”, “staging”, and “QA” environments, you’re leaving a lot of speed and reliability on the table.&lt;/p&gt;

&lt;p&gt;Modern teams are quietly switching to ephemeral environments—short‑lived, on‑demand environments spun up per feature, per branch, or even per pull request. They disappear when you’re done, but the impact on quality, collaboration, and delivery speed is very real.&lt;/p&gt;

&lt;p&gt;This article breaks down what ephemeral environments are, why they matter, and how to think about adopting them in your org.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Are Ephemeral Environments?
&lt;/h3&gt;

&lt;p&gt;An ephemeral environment is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On-demand&lt;/strong&gt;: created automatically (or via a simple self-service action) when you need it&lt;br&gt;
&lt;strong&gt;Isolated&lt;/strong&gt;: scoped to a branch, feature, ticket, or pull request&lt;br&gt;
Short‑lived: destroyed when the work is merged, abandoned, or after a TTL&lt;br&gt;
&lt;strong&gt;Prod-like&lt;/strong&gt;: runs the same stack (or a close approximation) as production&lt;/p&gt;

&lt;p&gt;Concretely, this is often:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A full stack (frontend, backend services, DBs, queues) spun up per PR&lt;/li&gt;
&lt;li&gt;A partial stack (only the service under change + its dependencies) with smart routing&lt;/li&gt;
&lt;li&gt;Provisioned via Kubernetes namespaces, separate clusters, or cloud resources tied to a unique ID (e.g., feature-1234)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of five teams fighting over staging, each PR gets its own “mini-staging” that matches production closely enough for serious testing and stakeholder review.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Ephemeral Environments Matter Now
&lt;/h3&gt;

&lt;p&gt;Monolith-era release cycles could survive with shared environments. Today’s reality is different:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Microservices and distributed systems&lt;/li&gt;
&lt;li&gt;Multiple teams shipping concurrently&lt;/li&gt;
&lt;li&gt;CI/CD pipelines pushing to production multiple times a day&lt;/li&gt;
&lt;li&gt;Product and design demanding faster iteration and feedback&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this world, environment contention and configuration drift become silent killers of velocity.&lt;/p&gt;

&lt;p&gt;Ephemeral environments address several pain points:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. They Remove the “Who Broke Staging?” Problem&lt;/strong&gt;&lt;br&gt;
Shared long‑lived envs suffer from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Random breakages because someone else deployed their half-finished change&lt;/li&gt;
&lt;li&gt;Dirty data and hard‑to‑reproduce bugs&lt;/li&gt;
&lt;li&gt;“Works on my machine, not on staging” conflicts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With ephemeral envs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your environment is yours alone&lt;/li&gt;
&lt;li&gt;You test your changes in isolation&lt;/li&gt;
&lt;li&gt;When it’s broken, you know exactly where to look&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This drastically reduces the cognitive load and finger‑pointing around shared staging.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. They Shift Quality Left – For Real&lt;/strong&gt;&lt;br&gt;
We love to say “shift left,” but if the only realistic prod-like environment is staging, you’re not really shifting much.&lt;/p&gt;

&lt;p&gt;Ephemeral envs bring prod‑like validation to the PR level:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run integration and end‑to‑end tests against a realistic environment per change&lt;/li&gt;
&lt;li&gt;Reproduce tricky issues using the exact code and configuration of the PR&lt;/li&gt;
&lt;li&gt;Validate infrastructure changes (Helm charts, Terraform modules, feature flags) before they touch shared infra
This reduces late surprises and production hotfixes—quality improves without slowing down delivery.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. They Unlock True “Preview” Workflows for Stakeholders&lt;/strong&gt;&lt;br&gt;
Non‑developers struggle to review work on Git diffs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Product wants to click through the new flow&lt;/li&gt;
&lt;li&gt;Design wants to see how the UI looks on different devices&lt;/li&gt;
&lt;li&gt;Sales wants to demo a feature to a specific customer segment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With ephemeral environments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every PR can have a preview URL&lt;/li&gt;
&lt;li&gt;Stakeholders can play with the feature before it merges&lt;/li&gt;
&lt;li&gt;Feedback loops tighten: “Try this PR link” beats “Wait for staging” or “I’ll send you a video”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a massive dev‑to‑business bridge: features become tangible earlier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. They Reduce Long‑Lived Staging/QA Maintenance Tax&lt;/strong&gt;&lt;br&gt;
Maintaining a couple of static environments sounds cheap—until you add up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Time spent cleaning test data&lt;/li&gt;
&lt;li&gt;Manual config tweaks that drift from prod over time&lt;/li&gt;
&lt;li&gt;Fixing broken staging pipelines because ten teams rely on it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ephemeral envs flip the model:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You codify environment creation (IaC, Helm, Kustomize, etc.)&lt;/li&gt;
&lt;li&gt;Environments become cattle, not pets&lt;/li&gt;
&lt;li&gt;Staging can be simplified (or even retired) in some orgs
You trade ongoing manual babysitting for upfront automation—a better investment for scaling teams.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5. They Make Platform Engineering and DevEx Tangible&lt;/strong&gt;&lt;br&gt;
Ephemeral environments naturally sit inside an internal developer platform:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Self‑service UI or CLI to spin up an environment per branch&lt;/li&gt;
&lt;li&gt;Guardrails via templates, policies, quotas, and TTLs&lt;/li&gt;
&lt;li&gt;Integrated observability, logs, and metrics per environment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For platform teams, ephemeral envs are a high‑leverage way to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Standardize how services run&lt;/li&gt;
&lt;li&gt;Encapsulate best practices (health checks, security, resource limits)&lt;/li&gt;
&lt;li&gt;Offer something developers feel immediately (“I get my own prod-like environment in minutes”)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When Are Ephemeral Environments a Good Fit?
&lt;/h3&gt;

&lt;p&gt;They shine in certain scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Microservices / polyrepo / monorepo with many teams
**- **High release frequency&lt;/strong&gt; (multiple deployments per day/week)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Complex integrations&lt;/strong&gt; (multiple backends, APIs, 3rd‑party systems)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Heavy UI/UX iteration&lt;/strong&gt;, where visual review is key&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Regulated environments&lt;/strong&gt;, where you want strong separation between pre‑prod and prod&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They are less critical—but still helpful—if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You have a small monolith with rare releases&lt;/li&gt;
&lt;li&gt;Your “staging” is truly simple and reliable&lt;/li&gt;
&lt;li&gt;Most changes are trivial and low‑risk
In practice, once teams get used to branch/PR‑scoped environments, it is hard to go back.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Common Challenges and Trade‑Offs
&lt;/h3&gt;

&lt;p&gt;It’s not all magic. You need to be realistic about:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Infrastructure Cost&lt;/strong&gt;&lt;br&gt;
Spinning up full stacks per PR can be expensive if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Resource limits are not set properly&lt;/li&gt;
&lt;li&gt;Environments live forever because there is no TTL or cleanup&lt;/li&gt;
&lt;li&gt;Every environment runs heavyweight databases or external services&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Use quotas and automatic TTLs&lt;/li&gt;
&lt;li&gt;Right‑size resources for pre‑prod (smaller instances, fewer replicas)&lt;/li&gt;
&lt;li&gt;Use shared backing services where it makes sense (read-only data, mocks)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Data Management&lt;/strong&gt;&lt;br&gt;
Prod‑like environments need prod‑like data patterns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You often cannot copy full production databases&lt;/li&gt;
&lt;li&gt;You may need anonymized or synthetic data&lt;/li&gt;
&lt;li&gt;Tests may rely on certain data shapes and volumes&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Automated DB seeding/migration scripts per environment&lt;/li&gt;
&lt;li&gt;Subset/snapshot of prod data with anonymization&lt;/li&gt;
&lt;li&gt;Clear strategy for stateful vs. stateless services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Complexity of Orchestration&lt;/strong&gt;&lt;br&gt;
Ephemeral envs require:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reliable IaC templates (Terraform, Pulumi, CloudFormation)&lt;/li&gt;
&lt;li&gt;Kubernetes manifests/Helm charts that can be parameterized per env&lt;/li&gt;
&lt;li&gt;Routing, DNS, and SSL automation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where platform engineering and internal tools pay off. It’s not a free feature; it’s a capability to build incrementally.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Start: A Pragmatic Adoption Path
&lt;/h3&gt;

&lt;p&gt;You don’t need a fully automated, company‑wide system on day one. A sensible path:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start with one product or team&lt;/li&gt;
&lt;li&gt;Automate environment creation for PRs&lt;/li&gt;
&lt;li&gt;Simplify data and dependencies early&lt;/li&gt;
&lt;li&gt;Add TTLs and cost controls from day one&lt;/li&gt;
&lt;li&gt;Observe usage and iterate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Over time, ephemeral envs evolve from an experiment into a core part of your delivery workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  The “Why Now” for Leaders
&lt;/h3&gt;

&lt;p&gt;For engineering and platform leaders, ephemeral environments are not just a technical choice—they’re a &lt;strong&gt;DevEx and business decision&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Faster feedback → faster shipping → higher feature throughput&lt;/li&gt;
&lt;li&gt;Lower change risk → fewer incidents → more stable roadmap&lt;/li&gt;
&lt;li&gt;Better collaboration → less friction between dev, QA, product, and sales&lt;/li&gt;
&lt;li&gt;Stronger platform foundation → easier to scale teams and services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In a market where developer productivity and time to value are increasingly strategic, ephemeral environments are a practical, observable lever you can pull.&lt;/p&gt;

&lt;p&gt;If you’re still relying on a couple of long‑lived staging environments, this is a good time to ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What would it look like if every meaningful change had its own safe, isolated, prod‑like sandbox?&lt;br&gt;
That answer is, essentially, your roadmap to ephemeral environments.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Follow us: &lt;a href="https://www.exemplar.dev/" rel="noopener noreferrer"&gt;Exemplar Dev&lt;/a&gt; to know more about upcoming developer platform which will enable you to create ephemeral environment.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>development</category>
      <category>devex</category>
    </item>
    <item>
      <title>Kubernetes Monitoring with Grafana</title>
      <dc:creator>Pratik Mahalle</dc:creator>
      <pubDate>Tue, 20 Jan 2026 02:38:35 +0000</pubDate>
      <link>https://dev.to/pratikmahalle/-kubernetes-monitoring-with-grafana-25e5</link>
      <guid>https://dev.to/pratikmahalle/-kubernetes-monitoring-with-grafana-25e5</guid>
      <description>&lt;p&gt;As a DevOps engineer working extensively with Kubernetes, I've learned that effective monitoring isn't just about collecting metrics - it's about gaining actionable insights that help you maintain cluster health and quickly troubleshoot issues. In this post, I'll share my experience using Grafana to monitor Kubernetes environments and some practical tips I've picked up along the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Grafana for Kubernetes?
&lt;/h2&gt;

&lt;p&gt;Kubernetes generates an overwhelming amount of metrics. Without proper visualization, you're essentially flying blind. Grafana has become my go-to tool because it provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Beautiful, customizable dashboards that make complex data digestible&lt;/li&gt;
&lt;li&gt;Seamless integration with Prometheus and other data sources&lt;/li&gt;
&lt;li&gt;Powerful alerting capabilities&lt;/li&gt;
&lt;li&gt;A strong community with pre-built dashboards&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Essential Stack
&lt;/h2&gt;

&lt;p&gt;My monitoring stack(These are not also mine:) typically includes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prometheus&lt;/strong&gt; - for metrics collection and storage&lt;br&gt;
&lt;strong&gt;Grafana&lt;/strong&gt; - for visualization and dashboards&lt;br&gt;
&lt;strong&gt;kube-state-metrics&lt;/strong&gt; - for Kubernetes-specific metrics&lt;br&gt;
&lt;strong&gt;node-exporter&lt;/strong&gt; - for node-level system metrics&lt;br&gt;
&lt;strong&gt;Loki&lt;/strong&gt; - (optional) for log aggregation&lt;/p&gt;

&lt;p&gt;This combination gives you comprehensive visibility into your cluster's health and performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Metrics I Monitor
&lt;/h2&gt;

&lt;p&gt;After managing multiple Kubernetes clusters, I've identified the metrics that matter most:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cluster-Level Metrics:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node resource utilization (CPU, memory, disk)&lt;/li&gt;
&lt;li&gt;Pod count and status across namespaces&lt;/li&gt;
&lt;li&gt;Cluster capacity and resource requests vs limits&lt;/li&gt;
&lt;li&gt;API server latency and error rates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Application-Level Metrics:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pod resource consumption&lt;/li&gt;
&lt;li&gt;Container restart counts&lt;/li&gt;
&lt;li&gt;Application-specific metrics (request rates, error rates, latency)&lt;/li&gt;
&lt;li&gt;Persistent volume usage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Network Metrics:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Network traffic between pods and services&lt;/li&gt;
&lt;li&gt;Ingress/egress bandwidth&lt;/li&gt;
&lt;li&gt;Service endpoint availability&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Dashboard Setup Tips(These are actually not mine)
&lt;/h2&gt;

&lt;p&gt;Over time, I've developed some best practices for Grafana dashboards:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Start with community dashboards.&lt;/strong&gt; The Grafana dashboard repository has excellent Kubernetes dashboards. My favorites include the Kubernetes Cluster Monitoring dashboard and the Node Exporter Full dashboard. Don't reinvent the wheel—start with these and customize as needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Organize by concern.&lt;/strong&gt; I maintain separate dashboards for different audiences. A high-level cluster overview for leadership, detailed node metrics for infrastructure teams, and application-specific dashboards for developers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use variables effectively.&lt;/strong&gt; Dashboard variables for namespace, pod, and container allow you to create reusable dashboards that work across your entire infrastructure. This saves tremendous time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Set up meaningful alerts.&lt;/strong&gt; Alerts should be actionable. I've learned to avoid alert fatigue by focusing on conditions that genuinely require intervention, like sustained high CPU usage, pod crash loops, or disk space approaching capacity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mistake to Avoid
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Over-monitoring.&lt;/strong&gt; You don't need to visualize every single metric. Focus on what helps you make decisions and troubleshoot issues.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ignoring resource limits.&lt;/strong&gt; Make sure your Prometheus and Grafana deployments have appropriate resource limits. I've seen monitoring systems become the problem when they consume too many cluster resources.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Static thresholds.&lt;/strong&gt; CPU usage that's normal for one application might be critical for another. Context matters when setting alert thresholds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Impact
&lt;/h2&gt;

&lt;p&gt;Implementing proper Grafana monitoring has transformed how my team operates. We can now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Identify performance bottlenecks before they impact users&lt;/li&gt;
&lt;li&gt;Make data-driven decisions about scaling and resource allocation&lt;/li&gt;
&lt;li&gt;Reduce mean time to resolution (MTTR) for incidents&lt;/li&gt;
&lt;li&gt;Demonstrate infrastructure health to stakeholders&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One specific example: we identified a memory leak in a microservice by noticing a steady upward trend in container memory usage over several days. Without Grafana's visualization, this would have been much harder to spot in raw metrics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;If you're new to Grafana and Kubernetes monitoring, here's my recommended path:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Deploy Prometheus using the kube-prometheus-stack Helm chart (it includes Grafana, Prometheus, and common exporters)&lt;/li&gt;
&lt;li&gt;Import community dashboards for Kubernetes cluster monitoring&lt;/li&gt;
&lt;li&gt;Explore the dashboards and understand what each panel shows&lt;/li&gt;
&lt;li&gt;Customize dashboards based on your specific needs&lt;/li&gt;
&lt;li&gt;Set up basic alerts for critical conditions&lt;/li&gt;
&lt;li&gt;Iterate and improve based on real incidents and questions your team asks&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Grafana has become an indispensable tool in my Kubernetes toolkit. The visibility it provides into cluster health, resource utilization, and application performance makes it easier to maintain reliable systems and quickly resolve issues when they arise.&lt;/p&gt;

&lt;p&gt;The key is to start simple, use community resources, and gradually build more sophisticated monitoring as you understand your specific needs. &lt;/p&gt;

&lt;p&gt;What's your experience with Grafana and Kubernetes? I'd love to hear about your monitoring setup and any tips you've discovered along the way.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Are you using Grafana for Kubernetes monitoring? Share your experiences in the comments below, or connect with me to discuss observability practices.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>opensource</category>
      <category>kubernetes</category>
      <category>grafana</category>
    </item>
    <item>
      <title>From DevOps to Platform Engineering in the AI Era</title>
      <dc:creator>Pratik Mahalle</dc:creator>
      <pubDate>Mon, 05 Jan 2026 13:55:24 +0000</pubDate>
      <link>https://dev.to/pratikmahalle/from-devops-to-platform-engineering-in-the-ai-era-5bg9</link>
      <guid>https://dev.to/pratikmahalle/from-devops-to-platform-engineering-in-the-ai-era-5bg9</guid>
      <description>&lt;p&gt;I've been talking to a lot of DevOps engineers lately, and the same question keeps coming up: "Is platform engineering just another hype, or should I actually care about this?"&lt;/p&gt;

&lt;p&gt;Here's what I've learned: Platform engineers are earning up to 27% more than DevOps roles. But that's not really why this matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Changed
&lt;/h2&gt;

&lt;p&gt;Six months ago, every company was scrambling to add AI tools. Give developers Copilot, throw in some AI agents, problem solved, right?&lt;/p&gt;

&lt;p&gt;Wrong.&lt;/p&gt;

&lt;p&gt;Rickey Zachary from Thoughtworks spent 200 days on the road in 2025, and he kept seeing the same pattern: AI doesn't fix broken systems. It just breaks them faster.&lt;/p&gt;

&lt;p&gt;Your documentation is scattered across Confluence, Notion, and somebody's Google Drive? AI can't help. Your deployment process has seven manual approval steps? AI agents will just fail at step three instead of step seven. Technical debt you've been working around for years? AI trips over it immediately.&lt;/p&gt;

&lt;p&gt;The uncomfortable truth is that AI amplifies whatever you already have. Good systems get better. Messy systems get messier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Platform Engineering
&lt;/h2&gt;

&lt;p&gt;This is where platform engineering comes in, and why it's not just DevOps with a new name.&lt;/p&gt;

&lt;p&gt;DevOps taught us to automate and collaborate. Platform engineering asks a different question: What if we built infrastructure as an actual product that developers want to use?&lt;/p&gt;

&lt;p&gt;You think about the last time a developer asked you to provision something. You probably:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Got a Slack message or ticket&lt;/li&gt;
&lt;li&gt;Did the thing manually (or ran your script)&lt;/li&gt;
&lt;li&gt;Maybe documented it somewhere&lt;/li&gt;
&lt;li&gt;Repeated this next week with a different developer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Platform engineering means building a self-service portal where developers do it themselves. You spend time building the product once, not doing the same task repeatedly.&lt;/p&gt;

&lt;p&gt;The mindset shift is huge. You're not just automating tasks - you're designing experiences.&lt;/p&gt;

&lt;h2&gt;
  
  
  The AI Connection
&lt;/h2&gt;

&lt;p&gt;Here's why timing matters: AI needs platforms to work.&lt;/p&gt;

&lt;p&gt;Organizations are figuring out that giving developers AI tools without fixing the underlying infrastructure is pointless. Research shows that 86% of organizations now believe platform engineering is essential for getting real value from AI.&lt;/p&gt;

&lt;p&gt;And there's a dual opportunity here:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Building AI-powered platforms&lt;/strong&gt; means using AI to make your platforms smarter. Imagine documentation that answers questions, systems that predict issues before they happen, or troubleshooting that actually helps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Building platforms for AI&lt;/strong&gt; means creating infrastructure that ML teams need. They're struggling with model deployment, GPU management, and data pipelines. If you can solve these problems, you're suddenly very valuable.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Actually Changes
&lt;/h2&gt;

&lt;p&gt;The skills you need aren't completely different. You already know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Infrastructure as code&lt;/li&gt;
&lt;li&gt;CI/CD pipelines&lt;/li&gt;
&lt;li&gt;Kubernetes and containers&lt;/li&gt;
&lt;li&gt;Cloud platforms&lt;/li&gt;
&lt;li&gt;Monitoring and security&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Add to that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Thinking about users (yes, developers are users)&lt;/li&gt;
&lt;li&gt;Designing APIs people want to use&lt;/li&gt;
&lt;li&gt;Writing documentation that doesn't suck&lt;/li&gt;
&lt;li&gt;Measuring developer experience, not just uptime&lt;/li&gt;
&lt;li&gt;Building things people choose to use, not have to use&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last point is crucial. Platform engineering fails when you build something and force people to use it. It succeeds when developers actively choose your platform because it makes their lives easier. And now here is the bigger problem!&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Start
&lt;/h2&gt;

&lt;p&gt;You don't need permission to start thinking like a platform engineer.&lt;/p&gt;

&lt;p&gt;Pick the most annoying repetitive request you get. Build self-service for it. Make it so good that people stop asking you.&lt;/p&gt;

&lt;p&gt;Document it like you're explaining to a friend, not writing a technical manual.&lt;/p&gt;

&lt;p&gt;Measure the impact. How much time did you save? How many tickets disappeared?&lt;/p&gt;

&lt;p&gt;Then do it again with something bigger.&lt;/p&gt;

&lt;p&gt;I've seen people transition by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Building an internal portal that cut provisioning time from 3 days to 10 minutes&lt;/li&gt;
&lt;li&gt;Creating golden paths for deployments that reduced incidents by 60%&lt;/li&gt;
&lt;li&gt;Specializing in MLOps infrastructure when their company started AI initiatives&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of them waited for a platform engineering job posting. They created platform engineering within their DevOps roles, proved the value, and the career followed.&lt;/p&gt;

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

&lt;p&gt;Look, AI isn't replacing platform engineers. If anything, it's making the role more critical.&lt;/p&gt;

&lt;p&gt;But the DevOps engineer who just keeps doing what they've been doing? That might be a harder position in two years.&lt;/p&gt;

&lt;p&gt;The difference isn't about learning every new technology. It's about shifting from "I automate things" to "I build products that enable people."&lt;/p&gt;

&lt;p&gt;That's the transition. That's why it matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where I'd Start
&lt;/h2&gt;

&lt;p&gt;If this resonates and you want to explore it:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This week:&lt;/strong&gt; Talk to three developers. Ask them what's annoying about your infrastructure. Really listen.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This month:&lt;/strong&gt; Fix one of those problems with self-service. Document it well. Measure the impact.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This quarter:&lt;/strong&gt; Find &lt;a href="https://platformengineering.org/" rel="noopener noreferrer"&gt;platform engineering&lt;/a&gt; community. Join their &lt;a href="https://platformengin-b0m7058.slack.com/" rel="noopener noreferrer"&gt;Slack&lt;/a&gt; and see what others are building.&lt;/p&gt;

&lt;p&gt;The career path isn't mysterious. Build things that make developers' lives better. Measure the impact. Share what you learn. Repeat.&lt;/p&gt;

&lt;p&gt;Platform engineering isn't gatekept behind certifications or special knowledge. It's a mindset you can adopt starting today.&lt;/p&gt;

&lt;p&gt;The question is whether you will.&lt;/p&gt;

&lt;p&gt;Thank you for reading. See you soon!&lt;/p&gt;

</description>
      <category>devops</category>
      <category>platformengineering</category>
      <category>ai</category>
      <category>career</category>
    </item>
    <item>
      <title>How ventoy help me to install Window</title>
      <dc:creator>Pratik Mahalle</dc:creator>
      <pubDate>Tue, 30 Dec 2025 17:01:17 +0000</pubDate>
      <link>https://dev.to/pratikmahalle/how-ventoy-help-me-to-install-window-24pj</link>
      <guid>https://dev.to/pratikmahalle/how-ventoy-help-me-to-install-window-24pj</guid>
      <description>&lt;p&gt;&lt;strong&gt;After Four Years Using Arch Linux, I Finally Decided to Switch Back to Windows&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After four years of using Arch Linux, I finally decided to switch back to Windows. I know that was quite a strange decision, as I was never a fan of Windows. I was always committed to Linux and its security. But time changes, and so do we.&lt;/p&gt;

&lt;p&gt;I always used &lt;a href="https://etcher.balena.io/" rel="noopener noreferrer"&gt;Balena Etcher&lt;/a&gt; for flashing ISOs, as I really love that product. Huge shoutout to them for making our lives easier.&lt;/p&gt;

&lt;p&gt;After almost getting my pendrive ready to boot, I finally started to boot Windows, but one issue occurred saying, "Required media driver not found." I was like, "Did I make a mistake while flashing the ISO?" I even tried to reinstall the ISO, but the same issue persisted. After doing some research, I got to know that the media driver issue happens because Windows Setup can't detect the internal storage usually due to missing storage controller drivers or USB compatibility problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  How &lt;a href="https://www.ventoy.net/en/index.html" rel="noopener noreferrer"&gt;Ventoy&lt;/a&gt; Solved This Issue
&lt;/h2&gt;

&lt;p&gt;This is where Ventoy became my lifesaver.&lt;/p&gt;

&lt;p&gt;Traditional tools like Balena Etcher work by extracting the ISO contents and writing them to the USB drive with a bootloader. This process can sometimes mess with the driver structure or how Windows Setup accesses the installation media and internal storage.&lt;/p&gt;

&lt;p&gt;Ventoy works completely differently. It creates a bootable environment on your USB drive where ISO files are kept as - is - no extraction, no modification. You literally just copy the ISO file onto the USB like a regular file. When you boot, Ventoy loads the ISO directly from the file, maintaining its original structure and all embedded drivers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why this fixed my problem:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The "media driver not found" error happens because Windows Setup loses access to either the USB installation media or can't detect the internal storage (HDD/SSD/NVMe). With traditional flashing methods, the USB controller drivers or storage drivers don't always work properly during setup.&lt;/p&gt;

&lt;p&gt;Ventoy bypasses this entirely because it boots the ISO in its virgin state, Windows gets all its drivers exactly as Microsoft packaged them, without any modifications from the flashing process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I did:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Downloaded Ventoy and installed it on my USB drive (one - time setup)&lt;/li&gt;
&lt;li&gt;Simply copied my Windows ISO file directly onto the USB&lt;/li&gt;
&lt;li&gt;Booted from the USB and selected the Windows ISO from Ventoy's menu&lt;/li&gt;
&lt;li&gt;Windows installation went smooth, internal storage detected, no driver errors&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For me the best thing will be of this tool is, I can keep multiple ISOs on the same USB - Windows, Linux distros, recovery tools i.e. all on one drive. No more reformatting every time and you dont even need extra USB because I don't have that, that is why I find this way :)&lt;/p&gt;

&lt;p&gt;So sometimes the simplest solution is the best one and ventoy proved that by just not messing with the original ISO structure, everything works as it should.&lt;/p&gt;

&lt;p&gt;If you’ve been through a similar switch or hit an unexpected installer issue, I’d be genuinely interested in hearing how your experience went.&lt;/p&gt;

&lt;p&gt;Thank you for reading!&lt;/p&gt;

</description>
      <category>microsoft</category>
      <category>linux</category>
    </item>
    <item>
      <title>How can we integrate Bolna AI With Google Sheets?</title>
      <dc:creator>Pratik Mahalle</dc:creator>
      <pubDate>Mon, 17 Nov 2025 08:10:57 +0000</pubDate>
      <link>https://dev.to/pratikmahalle/how-can-we-integrate-bolna-ai-with-google-sheets-5228</link>
      <guid>https://dev.to/pratikmahalle/how-can-we-integrate-bolna-ai-with-google-sheets-5228</guid>
      <description>&lt;p&gt;You know that feeling when you have a list of 50 people to call for reminders, confirmations, or surveys, and you're sitting there thinking "there has to be a better way than dialing each number manually"? Well, I just discovered something that's going to completely change how you think about phone outreach, and I had to share it with you right away.&lt;/p&gt;

&lt;p&gt;Picture this: You have a spreadsheet with phone numbers. You hit a button. AI agents start making those calls automatically. The conversations happen naturally. Results get written back to your spreadsheet. All without you lifting a finger. Sounds too good to be true? That's exactly what &lt;strong&gt;Bolna + Google Sheets&lt;/strong&gt; makes possible, and honestly, it's brilliant.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem Everyone Faces (But Nobody Talks About)
&lt;/h2&gt;

&lt;p&gt;Whether you're running a small business, managing events, or handling customer support, phone calls are still the most effective way to reach people. But they're also the most time-consuming. Manual dialing, repeating the same script, logging results—it's exhausting and kills productivity.&lt;/p&gt;

&lt;p&gt;Email? Often ignored. SMS? Great, but limited. Phone calls? Personal, direct, and impossible to ignore. But who has time to make 50 calls a day?&lt;/p&gt;

&lt;p&gt;That's where the magic of &lt;strong&gt;Bolna's AI calling platform&lt;/strong&gt; combined with the simplicity of &lt;strong&gt;Google Sheets&lt;/strong&gt; comes in. You get the power of AI-driven voice calls without writing a single line of backend code.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Makes Bolna + Google Sheets Special?
&lt;/h2&gt;

&lt;p&gt;Here's what got me genuinely excited about this integration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;No Infrastructure Required&lt;br&gt;
You don't need servers, databases, or complex DevOps. Just a Google Sheet and a Bolna account. That's it. Set it up once, and you're done.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Real-Time Updates&lt;br&gt;
As calls happen, your spreadsheet updates automatically. You can see who's been called, who answered, and what was discussed—all in one place.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;AI That Actually Sounds Human&lt;br&gt;
Bolna's AI agents don't sound like robots. They handle conversations naturally, respond to questions, and even adapt to different situations. It's not just playing a recording—it's having real conversations.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How It Actually Works (The Simple Version)
&lt;/h2&gt;

&lt;p&gt;Think of it like this: your Google Sheet becomes a command center. Each row is a person to call. Mark a row as "pending," and Bolna's AI takes over. It makes the call, has the conversation, and writes back the result. You just check the sheet to see what happened.&lt;/p&gt;

&lt;p&gt;The best part? You can test it with your own number first. Call yourself, see how the AI sounds, and once you're comfortable, scale it to hundreds of calls.&lt;/p&gt;

&lt;p&gt;Alright, let's build this thing from scratch. Grab a coffee, and let's do this together. I'll walk you through every single step.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Set Up Your Bolna Account (5 minutes)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1.1 Create Your Account&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to &lt;a href="https://platform.bolna.ai" rel="noopener noreferrer"&gt;platform.bolna.ai&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Sign up with your email&lt;/li&gt;
&lt;li&gt;You'll get &lt;strong&gt;$5 in free credits&lt;/strong&gt; automatically—enough for 50-100 test calls&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;1.2 Verify Your Phone Number&lt;/strong&gt;&lt;br&gt;
This is crucial. Bolna requires verified numbers to prevent spam.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click on &lt;strong&gt;Settings&lt;/strong&gt; in the left sidebar&lt;/li&gt;
&lt;li&gt;Navigate to &lt;strong&gt;Verified Phone Numbers&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Add Number&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Enter your phone number in international format (e.g., +919876543210 or +12025551234)&lt;/li&gt;
&lt;li&gt;You'll receive an OTP—enter it&lt;/li&gt;
&lt;li&gt;Your number is now verified and ready to receive test calls&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;1.3 Generate Your API Key&lt;/strong&gt;&lt;br&gt;
This key is how your Google Sheet will talk to Bolna.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to &lt;strong&gt;Settings → API Keys&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create New API Key&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Give it a name like "Google Sheets Integration"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Copy the key and save it somewhere safe&lt;/strong&gt;—you won't see it again&lt;/li&gt;
&lt;li&gt;It looks something like: &lt;code&gt;bolna_live_abc123xyz456...&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Step 2: Create Your AI Agent (3 minutes)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;2.1 Navigate to Agents&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click &lt;strong&gt;Agents&lt;/strong&gt; in the left menu&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create New Agent&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2.2 Choose a Template&lt;/strong&gt;&lt;br&gt;
Bolna gives you pre-built templates. Pick one that matches your use case:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Appointment Reminder&lt;/strong&gt; - For reminding customers about bookings&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Survey Agent&lt;/strong&gt; - For collecting feedback&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lead Qualification&lt;/strong&gt; - For sales outreach&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;General Support&lt;/strong&gt; - For customer service calls&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this tutorial, let's pick &lt;strong&gt;Appointment Reminder&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.3 Customize Your Agent (Optional)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can edit the &lt;strong&gt;first message&lt;/strong&gt; the agent says&lt;/li&gt;
&lt;li&gt;Example: &lt;em&gt;"Hi, this is an automated reminder from [Your Company]. I'm calling to confirm your appointment scheduled for tomorrow at 3 PM. Can you confirm if you'll be able to make it?"&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Keep it short and natural&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2.4 Save and Copy Agent ID&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click &lt;strong&gt;Save&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;You'll see an &lt;strong&gt;Agent ID&lt;/strong&gt; (looks like &lt;code&gt;agent_abc123xyz&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Copy this—you'll need it in your script&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Step 3: Set Up Your Google Sheet (5 minutes)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;3.1 Create a New Google Sheet&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to &lt;a href="https://sheets.google.com" rel="noopener noreferrer"&gt;sheets.google.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Create a new spreadsheet&lt;/li&gt;
&lt;li&gt;Name it something like "Bolna Call Automation"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3.2 Set Up Your Columns&lt;/strong&gt;&lt;br&gt;
Create these exact column headers in Row 1:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;A&lt;/th&gt;
&lt;th&gt;B&lt;/th&gt;
&lt;th&gt;C&lt;/th&gt;
&lt;th&gt;D&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Phone Number&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Call ID&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Result&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;3.3 Add Your Test Data&lt;/strong&gt;&lt;br&gt;
Fill in a few rows like this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Phone Number&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;th&gt;Call ID&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;+919876543210&lt;/td&gt;
&lt;td&gt;pending&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;+12025551234&lt;/td&gt;
&lt;td&gt;pending&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Important formatting tip:&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make sure phone numbers are in &lt;strong&gt;E.164 format&lt;/strong&gt; (+CountryCodePhoneNumber)&lt;/li&gt;
&lt;li&gt;Format Column A as &lt;strong&gt;Plain Text&lt;/strong&gt; (Format → Number → Plain Text) so Google Sheets doesn't remove the "+"&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Step 4: Write the Google Apps Script (10 minutes)
&lt;/h3&gt;

&lt;p&gt;This is where the magic happens. Don't worry—I'll walk you through every line.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4.1 Open Apps Script Editor&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In your Google Sheet, click &lt;strong&gt;Extensions → Apps Script&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;You'll see a code editor with some default code&lt;/li&gt;
&lt;li&gt;Delete everything in there&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4.2 Paste This Complete Script&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BOLNA_API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YOUR_API_KEY_HERE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Paste your Bolna API key&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AGENT_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;YOUR_AGENT_ID_HERE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;      &lt;span class="c1"&gt;// Paste your agent ID&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;triggerCalls&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sheet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;SpreadsheetApp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getActiveSheet&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lastRow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getLastRow&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// Skip if only header row exists&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lastRow&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;No data rows found&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="c1"&gt;// Get all data rows (starting from row 2)&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lastRow&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;getValues&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;phoneNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rowNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// +2 because arrays start at 0 and we skip header&lt;/span&gt;

    &lt;span class="c1"&gt;// Only process rows marked as "pending"&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;phoneNumber&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pending&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;Logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Processing row &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;rowNumber&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;phoneNumber&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Make the API call to Bolna&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;callId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;makeBolnaCall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;phoneNumber&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Update the sheet with new status and call ID&lt;/span&gt;
        &lt;span class="nx"&gt;sheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rowNumber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;initiated&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Status column&lt;/span&gt;
        &lt;span class="nx"&gt;sheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rowNumber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;      &lt;span class="c1"&gt;// Call ID column&lt;/span&gt;

        &lt;span class="nx"&gt;Logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Call initiated successfully: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;callId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;Logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Error for row &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;rowNumber&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;sheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rowNumber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;sheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rowNumber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;makeBolnaCall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;phoneNumber&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://api.bolna.dev/call&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;agent_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AGENT_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;recipient_phone_number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;phoneNumber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;// You can add more options here:&lt;/span&gt;
    &lt;span class="c1"&gt;// user_data: { customer_name: "John Doe" }&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;post&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;contentType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Authorization&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;BOLNA_API_KEY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;muteHttpExceptions&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;UrlFetchApp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;statusCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getResponseCode&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;responseBody&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContentText&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nx"&gt;Logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`API Response Code: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;Logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`API Response Body: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;responseBody&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Check if the call was successful&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;statusCode&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Bolna API error (&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;): &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;responseBody&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;responseBody&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// Return the call ID from the response&lt;/span&gt;
  &lt;span class="k"&gt;return&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;call_id&lt;/span&gt; &lt;span class="o"&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;id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;updateCallStatuses&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sheet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;SpreadsheetApp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getActiveSheet&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lastRow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getLastRow&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lastRow&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lastRow&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;getValues&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nx"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;callId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;      &lt;span class="c1"&gt;// Call ID column&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;      &lt;span class="c1"&gt;// Status column&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rowNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Only check calls that are not yet completed&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callId&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;completed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;failed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;callData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getCallStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Update status&lt;/span&gt;
        &lt;span class="nx"&gt;sheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rowNumber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// If call is completed, add the result/summary&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;completed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;callData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;summary&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;callData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transcript_summary&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Call completed successfully&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="nx"&gt;sheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rowNumber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// If call failed, log the reason&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;failed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reason&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;callData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;failure_reason&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Call failed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="nx"&gt;sheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rowNumber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;Logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Error checking status for row &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;rowNumber&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getCallStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://api.bolna.dev/call/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;callId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;get&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Authorization&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;BOLNA_API_KEY&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;muteHttpExceptions&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;UrlFetchApp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;statusCode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getResponseCode&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;responseBody&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContentText&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Failed to get call status (&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;statusCode&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;): &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;responseBody&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;responseBody&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;resetAllToPending&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sheet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;SpreadsheetApp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getActiveSheet&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lastRow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getLastRow&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lastRow&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// Clear status, call ID, and result columns&lt;/span&gt;
  &lt;span class="nx"&gt;sheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lastRow&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;clearContent&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="c1"&gt;// Set all to pending&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;lastRow&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;sheet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getRange&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;setValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pending&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;Logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;All rows reset to pending&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4.3 Update Your Configuration&lt;/strong&gt;&lt;br&gt;
At the top of the script, replace:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;YOUR_API_KEY_HERE&lt;/code&gt; with your actual Bolna API key&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;YOUR_AGENT_ID_HERE&lt;/code&gt; with your actual agent ID&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4.4 Save the Script&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click the &lt;strong&gt;Save&lt;/strong&gt; icon (💾)&lt;/li&gt;
&lt;li&gt;Give your project a name like "Bolna Integration"&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 5: Test Your First Call (5 minutes)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;5.1 Run the Script Manually&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the Apps Script editor, select &lt;strong&gt;triggerCalls&lt;/strong&gt; from the function dropdown at the top&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Run&lt;/strong&gt; (▶️)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5.2 Authorize the Script&lt;/strong&gt;&lt;br&gt;
The first time you run it, Google will ask for permissions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click &lt;strong&gt;Review Permissions&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Choose your Google account&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Advanced → Go to &lt;a href="https://dev.tounsafe"&gt;Your Project Name&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Allow&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(Don't worry—this is safe. Google just shows this warning for custom scripts)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5.3 Check the Logs&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click &lt;strong&gt;Execution Log&lt;/strong&gt; at the bottom&lt;/li&gt;
&lt;li&gt;You should see: &lt;code&gt;Call initiated successfully: call_xyz123&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5.4 Your Phone Rings!&lt;/strong&gt;&lt;br&gt;
Within 10-20 seconds, your verified phone number should ring. Answer it and have a conversation with the AI agent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5.5 Watch Your Sheet Update&lt;/strong&gt;&lt;br&gt;
Go back to your Google Sheet. You should see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Status changed to &lt;strong&gt;"initiated"&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Call ID appeared in Column C&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 6: Set Up Automatic Status Updates (5 minutes)
&lt;/h3&gt;

&lt;p&gt;Right now, you have to manually check call status. Let's automate that.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6.1 Create a Trigger&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In Apps Script, click the &lt;strong&gt;clock icon&lt;/strong&gt; (⏰) on the left sidebar (Triggers)&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Add Trigger&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;6.2 Configure the Trigger&lt;/strong&gt;&lt;br&gt;
Set these values:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Choose which function to run:&lt;/strong&gt; &lt;code&gt;updateCallStatuses&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Choose which deployment:&lt;/strong&gt; &lt;code&gt;Head&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Select event source:&lt;/strong&gt; &lt;code&gt;Time-driven&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Select type of time trigger:&lt;/strong&gt; &lt;code&gt;Minutes timer&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Select minute interval:&lt;/strong&gt; &lt;code&gt;Every 1 minute&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;6.3 Save the Trigger&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click &lt;strong&gt;Save&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Authorize again if prompted&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, every minute, your sheet will automatically check if calls are completed and update the results!&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 7: See the Results
&lt;/h3&gt;

&lt;p&gt;After your call ends (usually 1-2 minutes), refresh your Google Sheet. You should see:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Phone Number&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;th&gt;Call ID&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;+919876543210&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;completed&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;call_xyz123&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Customer confirmed appointment for tomorrow at 3 PM&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The &lt;strong&gt;Result&lt;/strong&gt; column now contains a summary of what happened during the call!&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Love About This Approach
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;It's Transparent&lt;br&gt;
Everything happens in a spreadsheet you control. No black boxes. No hidden processes. Just rows of data you can see and manage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It's Flexible&lt;br&gt;
Want to add more fields? Just add columns. Need to change the script? Tweak it. It adapts to your workflow, not the other way around.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It's Scalable&lt;br&gt;&lt;br&gt;
Start with 5 calls. Scale to 500. The process is the same. You're not locked into any plan or paying per seat.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It's Accessible&lt;br&gt;
Even non-developers can set this up. If you can create a Google Sheet (and you probably can), you can build this.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Technical Bit (For Those Who Care)
&lt;/h2&gt;

&lt;p&gt;Under the hood, you're using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Bolna's REST API&lt;/strong&gt; to trigger calls and fetch status&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google Apps Script&lt;/strong&gt; (basically JavaScript) to connect your sheet to Bolna&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Triggers&lt;/strong&gt; to automate status updates every minute&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The script does three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reads rows marked "pending"&lt;/li&gt;
&lt;li&gt;Calls Bolna's API to initiate calls&lt;/li&gt;
&lt;li&gt;Polls call status and writes results back&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It's event-driven, lightweight, and doesn't require any server hosting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters (The Big Picture)
&lt;/h2&gt;

&lt;p&gt;AI phone calls aren't science fiction anymore. They're practical, affordable, and accessible to anyone. What used to require call centers and massive budgets now fits in a Google Sheet.&lt;/p&gt;

&lt;p&gt;This isn't about replacing humans—it's about letting AI handle the repetitive, predictable parts so humans can focus on what matters: complex problems, empathy, and decision-making.&lt;/p&gt;

&lt;p&gt;Whether you're a solo entrepreneur, a growing startup, or a team inside a larger company, this integration gives you superpowers. You can reach more people, faster, without sacrificing quality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;The best tools are the ones that just work. No unnecessary complexity. No vendor lock-in. No steep learning curve. Bolna + Google Sheets is exactly that—simple, powerful, and surprisingly fun to build.&lt;/p&gt;

&lt;p&gt;If you've been looking for a way to automate phone calls without hiring developers or buying expensive software, this is your answer. Give it a shot. Test it with your own number. See what happens when AI handles your outreach.&lt;/p&gt;

&lt;p&gt;Trust me, once you see your first automated call complete and the result appear in your spreadsheet, you'll wonder how you ever did it manually.&lt;/p&gt;

&lt;p&gt;Now go build something cool. And when it works, share it. The community needs more builders who aren't afraid to experiment.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Ready to start?&lt;/strong&gt; Head to &lt;a href="https://platform.bolna.ai" rel="noopener noreferrer"&gt;platform.bolna.ai&lt;/a&gt; and create your account. You're literally 20 minutes away from automated AI phone calls.&lt;/p&gt;

</description>
      <category>google</category>
      <category>productivity</category>
      <category>ai</category>
      <category>automation</category>
    </item>
    <item>
      <title>Is DevRel Just About Events, or Something Deeper?</title>
      <dc:creator>Pratik Mahalle</dc:creator>
      <pubDate>Fri, 10 Oct 2025 10:09:52 +0000</pubDate>
      <link>https://dev.to/aws-builders/is-devrel-just-about-events-or-something-deeper-40fc</link>
      <guid>https://dev.to/aws-builders/is-devrel-just-about-events-or-something-deeper-40fc</guid>
      <description>&lt;p&gt;"So you just travel and go to conferences?"&lt;/p&gt;

&lt;p&gt;That's usually what people say when I tell them I work as a  Developer Relations or DevRel. And look, I honestly get it. From the outside, it probably looks like I'm just collecting conference badges, having good food, free stickers and t-shirts.&lt;/p&gt;

&lt;p&gt;But after attending some big conference like KubeCon India, speaking at OpenSSF Community Day India, and hanging out at PyCon India, Bengaluru this year, I've got some thoughts to share with you all. Yeah, conferences are fun. But DevRel? It's way more interesting (and messier) than you'd think.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Conference Life Looks Cooler Than It Actually Is
&lt;/h2&gt;

&lt;p&gt;Let me paint you a picture. You're at KubeCon. There are thousands of people, companies booths everywhere, and someone's handing out yet another t-shirt you'll never wear. You're tired because you stayed up late debugging your demo that broke 10 minutes before your talk. Your phone's dying because you forgot your charger. And you're pretty sure you've had 6 cups of coffee today.&lt;/p&gt;

&lt;p&gt;Glamorous? Not exactly.&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%2Fh7rqb5p7mljj18rnwk3u.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%2Fh7rqb5p7mljj18rnwk3u.jpeg" alt="Pycon" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But then something cool happens. You meet someone who's been stuck on a problem for weeks, and he actually know how to help. Or someone comes up after your talk and says "Hey, that thing you mentioned? That's exactly what I needed and can you help me in that?." &lt;/p&gt;

&lt;p&gt;That's when it clicks. This isn't about the free food or the fancy venue. It's about actually being useful to people.&lt;/p&gt;

&lt;p&gt;At OpenSSF Community Day India, I gave my first real conference talk. Was I nervous? Absolutely. Did I rehearse it like 20 times? You bet. But standing there, talking about something I care about, and seeing people actually paying attention (not checking their phones!), that felt pretty great.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Conversations Happen in Random Places
&lt;/h2&gt;

&lt;p&gt;Here's what nobody tells you about conferences: The best stuff doesn't happen during the scheduled talks.&lt;/p&gt;

&lt;p&gt;At PyCon India, I had this conversation with a developer at the lunch table. We started talking about what he do in the Python community, and they shared their entire workflow, their pain points, why they chose certain tools over others in his work. I think, that 20-minute chat taught me more than any survey ever could.&lt;/p&gt;

&lt;p&gt;At KubeCon, someone came to me during a coffee break and showed me his side projects about the communtiy. Right there, between sessions, we debugged an issue together, he has. No slides, no agenda, just two people trying to solve a problem.&lt;/p&gt;

&lt;p&gt;These moments are gold. This is where you learn what developers actually struggle with, what they love, what makes them want to throw their laptop out the window(But can't).&lt;/p&gt;

&lt;h2&gt;
  
  
  Giving Talks Is Terrifying (But Worth It)
&lt;/h2&gt;

&lt;p&gt;Let's be real about speaking at conferences. It's scary.&lt;/p&gt;

&lt;p&gt;Before my OpenSSF talk, I was pacing backstage like I was about to take my final exam. What if nobody shows up? What if everyone shows up and I completely blank? What if my demo fails? (Spoiler: demos always fail. Plan accordingly, even my failed.)&lt;/p&gt;

&lt;p&gt;But here's the thing about giving talks - it forces you to really know your stuff. You can't just go and understand something. You need to explain it clearly enough that someone who's never seen it or heard it before can follow along with that.&lt;/p&gt;

&lt;p&gt;And when you're done? People come up with questions, ideas, their own experiences. Suddenly you're not just talking at people, you're having actual conversations about that topic. That's the fun part actually.&lt;/p&gt;

&lt;p&gt;Plus, there's something weirdly satisfying about seeing your slides on a big screen. Not gonna lie, that's pretty cool.&lt;br&gt;
This is my picture from my talk when my demo stop working!&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%2Fmjfapb978xr8i5jog1oo.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%2Fmjfapb978xr8i5jog1oo.jpeg" alt="OpenSSF Community Day India" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  DevRel Between Conferences (AKA The Actual Job)
&lt;/h2&gt;

&lt;p&gt;Okay, so what happens when you're not at a conference? Because that's will be like 95% of the time.&lt;/p&gt;

&lt;p&gt;Most of my days look like this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Writing docs that don't suck.&lt;/strong&gt; After hearing someone at PyCon say "I read your docs three times and still didn't get it," I learned that what makes sense to me might not make sense to everyone else. Now I try to write like I'm explaining it to a friend.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hanging out in community channels.&lt;/strong&gt; Someone's stuck at 2 AM trying to deploy something. You drop a quick tip that unblocks them. They're happy, you're happy, everyone's happy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Making sample apps and demos.&lt;/strong&gt; Because sometimes people just want to see "how do I actually use this thing?" Not theory. Not architecture diagrams. Just show me the code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Being the bridge between users and product teams.&lt;/strong&gt; When five different people tell you the same thing is confusing, that's feedback worth taking seriously.&lt;/p&gt;

&lt;p&gt;None of this is exciting enough for Instagram. But it's what actually helps people.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Unglamorous Truth
&lt;/h2&gt;

&lt;p&gt;DevRel has this reputation of being all fun and games. Travel! Events! Swag! And sure, those things exist. But nobody talks about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Answering the same question 47 times (and trying to sound enthusiastic on answer 47)&lt;/li&gt;
&lt;li&gt;Writing the tutorial that took you 8 hours for someone to read in 5 minutes&lt;/li&gt;
&lt;li&gt;Debugging someone else's setup over a spotty video call&lt;/li&gt;
&lt;li&gt;Realizing your blog post has a typo after 500 people have already read it&lt;/li&gt;
&lt;li&gt;Spending hours planning an event and having 3 people show up&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's not all highlight reels. Sometimes it's just showing up and doing the work, even when nobody's watching.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I Actually Like This Job
&lt;/h2&gt;

&lt;p&gt;Despite everything I just said, I genuinely love this work. Here's why:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You're constantly learning.&lt;/strong&gt; Every conversation teaches you something. Every question makes you think differently. You can't do DevRel and stay stagnant.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You meet genuinely interesting people.&lt;/strong&gt; At KubeCon, I met someone building cloud infrastructure for rural schools. At PyCon, I talked to developers building tools for climate research. These people are doing cool stuff, and you get to be part of their journey.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You see real impact.&lt;/strong&gt; When someone builds something because of a tutorial you wrote, or when a feature gets added because you advocated for it, that feels good. You're not just talking about technology, you're helping people use it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The community becomes your community.&lt;/strong&gt; You start recognizing faces at events. People remember you. You become part of something bigger than just your company or project.&lt;/p&gt;

&lt;h2&gt;
  
  
  What DevRel Actually Is
&lt;/h2&gt;

&lt;p&gt;I was at Open Source Summit India, and there Aditya Oberoi gave a talk on DevRel and he mentioned a very good definition of DevRel. As you can see that in the image below.&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%2F1qe4mjwnzjpjqeujh8t8.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%2F1qe4mjwnzjpjqeujh8t8.jpeg" alt="What is DevRel" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After going to these conferences, and having countless conversations, here's my take:&lt;/p&gt;

&lt;p&gt;I feel DevRel is a person who represents the company to the community and vice versa.&lt;/p&gt;

&lt;p&gt;It's about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Writing guides that actually make sense&lt;/li&gt;
&lt;li&gt;Answering questions without being condescending
&lt;/li&gt;
&lt;li&gt;Building tools that solve real problems&lt;/li&gt;
&lt;li&gt;Creating spaces where people feel comfortable asking for help&lt;/li&gt;
&lt;li&gt;Being honest when something's broken instead of making excuses&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yes, events are part of it. Speaking at conferences is part of it. But those are just the visible parts. The real work is everything else, the daily grind of helping people, listening to feedback, and trying to make things better. And these are the some real work which goes hidden.&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%2Flkbj6inopsch6ojsbdei.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%2Flkbj6inopsch6ojsbdei.jpeg" alt="DevRel" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  If You're Thinking About DevRel
&lt;/h2&gt;

&lt;p&gt;My advice will be? Don't do it for the travel or the stage time or just for the fame. Those things are bonuses, not the job honestly.&lt;/p&gt;

&lt;p&gt;But do it if you actually enjoy helping people. Do it if you get excited when someone finally understands something you explained. Do it if you care about making technology more accessible and less frustrating.&lt;/p&gt;

&lt;p&gt;And if you do end up at a conference like KubeCon or PyCon? Don't just collect swag and business cards. Have real conversations with he people and make friends. These friends will really help you in future. Ask people what they're building. Learn about their challenges. That's where the actual interesting stuff happens.&lt;/p&gt;

&lt;p&gt;Because at the end of the day, DevRel isn't about how many events you attended or how many talks you gave. It's about how many developers you actually helped. And honestly? That's a pretty good way to spend your time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;P.S.&lt;/strong&gt; — If you see me at a future conference, say hi! I promise I'm friendlier than I look when I'm frantically trying to find a power outlet 10 minutes before my talk.&lt;/p&gt;

</description>
      <category>devrel</category>
      <category>techtalks</category>
      <category>ai</category>
      <category>documentation</category>
    </item>
    <item>
      <title>MemU: Memory that works everywhere</title>
      <dc:creator>Pratik Mahalle</dc:creator>
      <pubDate>Sun, 17 Aug 2025 11:35:04 +0000</pubDate>
      <link>https://dev.to/pratikmahalle/memu-the-game-changer-for-digital-companions-27kh</link>
      <guid>https://dev.to/pratikmahalle/memu-the-game-changer-for-digital-companions-27kh</guid>
      <description>&lt;p&gt;You know how we were talking about those chatbots and digital assistants that seem to forget everything the moment you close the app? Well, I just discovered something that's going to completely change that game, and I had to tell you about it right away.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem We All Face
&lt;/h2&gt;

&lt;p&gt;Picture this: You're having deep conversations with your favourite digital companion, sharing personal stories, preferences,and  dreams, and gradually building what feels like a real relationship. Then you come back the next day, and... nothing. It's like talking to someone with amnesia who has to start from scratch every single time and I am kind of that person also.&lt;/p&gt;

&lt;p&gt;Frustrating, right? That's exactly what got the folks at NevaMind thinking, and they came up with something called &lt;a href="https://memu.pro/" rel="noopener noreferrer"&gt;MemU&lt;/a&gt; that honestly sounds too good to be true.&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%2F69e6uw8lm6cjej9kwd7e.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%2F69e6uw8lm6cjej9kwd7e.png" alt="memu Banner" width="800" height="302"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What Makes MemU Different
&lt;/h2&gt;

&lt;p&gt;Think of MemU as giving your digital companion a proper brain - not just the ability to chat, but genuine memory that works like yours and mine. Instead of forgetting everything after each conversation, it creates what they call an "intelligent memory folder" that actually learns and grows.&lt;/p&gt;

&lt;p&gt;Here's what completely amazed me: this thing doesn't just store random bits of conversation. It has a memory agent (basically like having a personal librarian in your head) that automatically decides what's worth remembering, what needs updating, and what can be forgotten. No more manually organising or structured data input - it just handles everything naturally.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Numbers That Made Me Do a Double-Take
&lt;/h2&gt;

&lt;p&gt;Okay, so I'm usually doubtful about these tech claims, but check this out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They're hitting &lt;strong&gt;92% accuracy&lt;/strong&gt; on memory benchmarks (that's insanely good)&lt;/li&gt;
&lt;li&gt;It can cut costs by up to &lt;strong&gt;90%&lt;/strong&gt; compared to traditional approaches&lt;/li&gt;
&lt;li&gt;Instead of processing tiny conversation fragments, it can handle hundreds of conversation turns at once&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%2Foh9x4rcxa2r1x8slwjae.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%2Foh9x4rcxa2r1x8slwjae.png" alt="Difference" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That last point is huge because it means developers don't have to constantly ping the system for every little memory operation. It's like the difference between having to consciously think about every step while walking versus just naturally walking to where you want to go.&lt;/p&gt;

&lt;h2&gt;
  
  
  How It Actually Works (The Cool Stuff)
&lt;/h2&gt;

&lt;p&gt;The most brilliant part is how memories connect to each other. Remember how our brains don't just store isolated facts but create these web-like connections between related thoughts? MemU does exactly that. Your memories become this living network where finding one thing naturally leads you to related memories.&lt;/p&gt;

&lt;p&gt;But here's the part that really got me excited - it keeps working even when you're offline. The memory agent analyzes existing memories, finds patterns, creates insights, and basically makes your knowledge base smarter over time. It's not just growing bigger; it's getting more intelligent.&lt;/p&gt;

&lt;p&gt;And just like human memory, it knows what to prioritize. Recent stuff stays easily accessible, while less important things naturally fade into the background. Your digital companion develops its own personality and understanding that's uniquely shaped by your interactions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Applications That Make Sense
&lt;/h2&gt;

&lt;p&gt;The creators designed this specifically for companion applications, and you can see why:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Personal Companions&lt;/strong&gt;: Finally, someone who actually remembers your favorite coffee order, that story about your childhood dog, and how you prefer to be comforted when you're stressed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Educational Assistants&lt;/strong&gt;: A tutor that remembers your learning style, what topics you struggle with, and builds on previous lessons naturally.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creative Partners&lt;/strong&gt;: Collaborators for writing, brainstorming, or projects who remember your creative preferences and can reference past ideas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Therapy and Wellness&lt;/strong&gt;: Digital support that understands your patterns, triggers, and what approaches work best for you personally.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three Ways to Try It Out
&lt;/h2&gt;

&lt;p&gt;What I love is that they've made this accessible regardless of your technical level:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cloud Version&lt;/strong&gt;: The easiest route - sign up at &lt;a href="https://app.memu.so" rel="noopener noreferrer"&gt;app.memu.so&lt;/a&gt;, get your API key, and you're literally three lines of code away from having persistent memory in your applications. They handle all the complex infrastructure stuff.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/NevaMind-AI/memU/blob/main/README.self_host.md" rel="noopener noreferrer"&gt;Self-Hosted&lt;/a&gt;&lt;/strong&gt;: For people who want complete control over their data and prefer running everything locally. Perfect if privacy is your main concern or if you want to customize everything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Enterprise&lt;/strong&gt;: Full commercial licensing with dedicated support, custom development, and all the enterprise-grade features you'd expect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters More Than You Think
&lt;/h2&gt;

&lt;p&gt;We're moving toward a world where our digital interactions become increasingly personal and meaningful. The difference between a forgettable chatbot experience and a genuinely helpful digital companion often comes down to memory.&lt;/p&gt;

&lt;p&gt;MemU isn't just solving a technical problem - it's enabling real relationships between people and their digital tools. When your companion remembers not just what you said, but understands the context, your preferences, and how you've grown over time, everything changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Open Source Thing
&lt;/h2&gt;

&lt;p&gt;Here's something I really respect about the team: they're committed to open source development, otherwise I wouldn't be writing about this one here. The core framework is available on GitHub under Apache License 2.0, which means the community can contribute, modify, and improve it together.&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%2Fquowrilwlbp87jpbkqre.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%2Fquowrilwlbp87jpbkqre.png" alt="open-source" width="800" height="209"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;They've got an active Discord community, regular updates on Twitter, and they're genuinely interested in feedback from developers and users alike.&lt;/p&gt;

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

&lt;p&gt;Look, I've seen plenty of "revolutionary" memory solutions that turned out to be mostly hype. But MemU feels different. The combination of high accuracy, practical implementation, and genuine understanding of what companion applications need makes this feel like a real breakthrough.&lt;/p&gt;

&lt;p&gt;The fact that they're achieving 92% accuracy while keeping costs low suggests they've solved some fundamental technical challenges that others haven't figured out yet. That is from this one. If you have to talk about this,let's connect on &lt;a href="https://x.com/pratikstwts" rel="noopener noreferrer"&gt;x.&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Want to Try It?
&lt;/h2&gt;

&lt;p&gt;If you're curious (and you should be), the easiest way is to check out their cloud version at &lt;a href="https://app.memu.so" rel="noopener noreferrer"&gt;app.memu.so&lt;/a&gt; otherwise try the &lt;a href="https://github.com/NevaMind-AI/memU/blob/main/README.self_host.md" rel="noopener noreferrer"&gt;community edition&lt;/a&gt; also. Even if you're not so called technical person, you can experiment with the API and see how persistent memory changes the conversation experience.&lt;/p&gt;

&lt;p&gt;What do you think? Does this sound like something you'd want to experiment with? I'm definitely planning to play around with it this weekend and also creating a demo on this and see what kind of companion experiences I can build.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Want to explore MemU yourself? Check out &lt;a href="https://memu.pro" rel="noopener noreferrer"&gt;memu.pro&lt;/a&gt; or dive straight into the code at their &lt;a href="https://github.com/NevaMind-AI/memU" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;. Join their Discord community to connect with other developers who are building the future of intelligent digital companions.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>database</category>
    </item>
    <item>
      <title>Chaos Engineering for Security: Breaking Systems To Strengthen Defenses</title>
      <dc:creator>Pratik Mahalle</dc:creator>
      <pubDate>Sun, 20 Jul 2025 12:45:03 +0000</pubDate>
      <link>https://dev.to/pratikmahalle/chaos-engineering-for-security-breaking-systems-to-strengthen-defenses-399j</link>
      <guid>https://dev.to/pratikmahalle/chaos-engineering-for-security-breaking-systems-to-strengthen-defenses-399j</guid>
      <description>&lt;p&gt;&lt;em&gt;I'm excited to be speaking about this topic at &lt;a href="https://events.linuxfoundation.org/openssf-community-day-india/program/schedule/" rel="noopener noreferrer"&gt;OpenSSF Community Day India&lt;/a&gt;, and wanted to share some insights on this fascinating intersection of chaos engineering and security.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When most people hear "chaos engineering," they immediately think of Netflix's famous Chaos Monkey randomly terminating servers to test system resilience. But what if we took that same philosophy and applied it to security? What if, instead of waiting for attackers to find our vulnerabilities, we intentionally broke our own systems to discover weaknesses first?&lt;/p&gt;

&lt;p&gt;Welcome to Security Chaos Engineering – a practice that's transforming how we think about proactive security testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security Testing Reality Check
&lt;/h2&gt;

&lt;p&gt;Let's start with some uncomfortable truths about modern security:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;277 days&lt;/strong&gt; - that's the average time it takes to detect a security breach(according to the theories)&lt;/li&gt;
&lt;li&gt;Security testing typically happens too late in the development cycle&lt;/li&gt;
&lt;li&gt;Most assumptions about security controls go completely untested&lt;/li&gt;
&lt;li&gt;Teams deploy defenses and hope they work, only discovering gaps during real incidents&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I've witnessed this pattern repeatedly in organizations I've worked with. Teams spend months perfecting their security configurations, only to discover during a real incident that their assumptions were wrong. That firewall rule they thought was bulletproof? It fails under load. The network segmentation they relied on? It breaks when pods start communicating unexpectedly.&lt;/p&gt;

&lt;p&gt;Here's the key question that changed how I think about security: &lt;strong&gt;What if we could break things safely and strengthen our defenses before attackers find our weaknesses?&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter Security Chaos Engineering
&lt;/h2&gt;

&lt;p&gt;This is where Security Chaos Engineering comes in - a proactive approach that flips the traditional security script:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Traditional Security Approach:&lt;/strong&gt;&lt;br&gt;
Wait for attacks → Respond to incidents → Fix what broke&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security Chaos Engineering Approach:&lt;/strong&gt;&lt;br&gt;
Inject controlled failures → Test security responses → Strengthen defenses proactively&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Definition&lt;/strong&gt;: Security Chaos Engineering is the practice of testing security controls and incident response procedures through controlled failure injection and attack simulation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Goal&lt;/strong&gt;: Find vulnerabilities and weaknesses before real attackers do, while building confidence in our defensive capabilities.&lt;/p&gt;

&lt;p&gt;The core principle remains simple: &lt;strong&gt;If we can break it in a controlled environment, we can fix it before an attacker exploits it.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Tools of the Trade
&lt;/h2&gt;

&lt;p&gt;Before we dive into practical examples, let's talk about the tools that make Security Chaos Engineering possible. Having the right toolkit is crucial for effective security chaos experiments.&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%2F8lw5ybxb5dgcf0rm2hev.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%2F8lw5ybxb5dgcf0rm2hev.png" alt="Tools" width="683" height="145"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Core Chaos Engineering Platforms
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;ChaosMesh&lt;/strong&gt;: My go-to choice for Kubernetes-native environments. It offers excellent security experiment support with intuitive YAML configurations and a solid web UI for monitoring experiments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LitmusChaos&lt;/strong&gt;: Perfect for complex, multi-step chaos workflows. It has extensive experiment templates and integrates well with CI/CD pipelines. The community is active and constantly adding new security-focused experiments.&lt;/p&gt;
&lt;h3&gt;
  
  
  Security Monitoring and Detection
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;KubeArmor&lt;/strong&gt;: Runtime security monitoring that integrates beautifully with chaos experiments. It can detect policy violations and unusual behavior patterns during your tests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Falco&lt;/strong&gt;: Essential for detecting suspicious activities during chaos experiments. Its rule-based detection engine helps identify when your experiments uncover real security issues.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Open Policy Agent (OPA)&lt;/strong&gt;: Useful for testing policy enforcement under various failure conditions.&lt;/p&gt;
&lt;h3&gt;
  
  
  Network and Infrastructure Tools
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Istio Service Mesh&lt;/strong&gt;: Provides detailed network observability during chaos experiments, helping you understand how security policies behave under stress.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Weave Scope&lt;/strong&gt;: Excellent for visualizing network topology and understanding blast radius during security chaos experiments.&lt;/p&gt;
&lt;h3&gt;
  
  
  Why Tool Selection Matters
&lt;/h3&gt;

&lt;p&gt;Each tool serves a specific purpose in the security chaos engineering workflow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Chaos platforms&lt;/strong&gt; inject the failures&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring tools&lt;/strong&gt; observe the impact&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security tools&lt;/strong&gt; detect when defenses fail&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network tools&lt;/strong&gt; help understand the scope of impact&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key is creating a cohesive toolchain where these components work together seamlessly.&lt;/p&gt;
&lt;h2&gt;
  
  
  Real-World Scenarios: Learning by Breaking
&lt;/h2&gt;

&lt;p&gt;Now that we have our toolkit ready, let me walk you through some practical scenarios where Security Chaos Engineering has proven invaluable.&lt;/p&gt;
&lt;h3&gt;
  
  
  Scenario 1: Testing Kubernetes Pod Compromise
&lt;/h3&gt;

&lt;p&gt;Imagine you have a Kubernetes cluster with what you believe is proper network segmentation. Your pods are isolated, your network policies are in place, and everything looks secure on paper.&lt;/p&gt;

&lt;p&gt;Here's how we can test this assumption:&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;# Using ChaosMesh to simulate a compromised pod&lt;/span&gt;
apiVersion: chaos-mesh.org/v1alpha1
kind: PodChaos
metadata:
  name: pod-compromise-test
spec:
  action: pod-kill
  mode: one
  selector:
    namespaces:
      - production
    labelSelectors:
      app: web-frontend
  scheduler:
    cron: &lt;span class="s2"&gt;"@every 10m"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But that's just the beginning. What we really want to test is what happens &lt;em&gt;after&lt;/em&gt; compromise:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Lateral Movement Testing&lt;/strong&gt;: Once we simulate a pod compromise, can the "attacker" move laterally to other services?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Exfiltration Simulation&lt;/strong&gt;: Can sensitive data be accessed from the compromised pod?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Privilege Escalation&lt;/strong&gt;: Can the compromised pod gain higher privileges?&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Scenario 2: Firewall Stress Testing
&lt;/h3&gt;

&lt;p&gt;Your firewall rules work perfectly under normal conditions, but what happens when your system is under stress? Here's a test I regularly run:&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;# Using LitmusChaos for network chaos experiments&lt;/span&gt;
apiVersion: litmuschaos.io/v1alpha1
kind: ChaosExperiment
metadata:
  name: network-loss-test
spec:
  definition:
    scope: Namespaced
    permissions:
      - apiGroups: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
        resources: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"pods"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
        verbs: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"create"&lt;/span&gt;,&lt;span class="s2"&gt;"delete"&lt;/span&gt;,&lt;span class="s2"&gt;"get"&lt;/span&gt;,&lt;span class="s2"&gt;"list"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    image: &lt;span class="s2"&gt;"litmuschaos/go-runner:latest"&lt;/span&gt;
    args:
      - &lt;span class="nt"&gt;-c&lt;/span&gt;
      - ./experiments &lt;span class="nt"&gt;-name&lt;/span&gt; network-loss
    &lt;span class="nb"&gt;command&lt;/span&gt;:
      - /bin/bash
    &lt;span class="nb"&gt;env&lt;/span&gt;:
      - name: NETWORK_PACKET_LOSS_PERCENTAGE
        value: &lt;span class="s1"&gt;'50'&lt;/span&gt;
      - name: TOTAL_CHAOS_DURATION
        value: &lt;span class="s1"&gt;'300'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This experiment simulates 50% packet loss for 5 minutes. During this chaos, we test:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do firewall rules still apply correctly?&lt;/li&gt;
&lt;li&gt;Are there any bypass opportunities when the network is degraded?&lt;/li&gt;
&lt;li&gt;How does the system behave when connections are intermittent?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Demo: Setting Up Your First Security Chaos Experiment
&lt;/h2&gt;

&lt;p&gt;Let me show you how to set up a basic security chaos engineering experiment using open-source tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Environment Setup
&lt;/h3&gt;

&lt;p&gt;First, let's set up a basic Kubernetes cluster with some security tools:&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;# Install ChaosMesh&lt;/span&gt;
curl &lt;span class="nt"&gt;-sSL&lt;/span&gt; https://mirrors.chaos-mesh.org/v2.6.2/install.sh | bash

&lt;span class="c"&gt;# Install KubeArmor for runtime security&lt;/span&gt;
kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; https://raw.githubusercontent.com/kubearmor/KubeArmor/main/deployments/kubearmor.yaml

&lt;span class="c"&gt;# Verify installations&lt;/span&gt;
kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; chaos-mesh
kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; kubearmor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Create a Vulnerable Application
&lt;/h3&gt;

&lt;p&gt;Let's deploy a simple web application with intentional security gaps:&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;vulnerable-app&lt;/span&gt;
  &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vulnerable-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;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vulnerable-app&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;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vulnerable-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;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;web&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:latest&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;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;
        &lt;span class="na"&gt;securityContext&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;runAsUser&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;  &lt;span class="c1"&gt;# Running as root - intentionally vulnerable&lt;/span&gt;
          &lt;span class="na"&gt;capabilities&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;NET_ADMIN"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;  &lt;span class="c1"&gt;# Excessive privileges&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Create Security Chaos Experiments
&lt;/h3&gt;

&lt;p&gt;Now, let's create experiments to test our assumptions:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Experiment 1: Pod Failure Under Attack Simulation&lt;/strong&gt;&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;chaos-mesh.org/v1alpha1&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;NetworkChaos&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;ddos-simulation&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;action&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;delay&lt;/span&gt;
  &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;all&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;namespaces&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;
    &lt;span class="na"&gt;labelSelectors&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vulnerable-app&lt;/span&gt;
  &lt;span class="na"&gt;delay&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;latency&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;10ms"&lt;/span&gt;
    &lt;span class="na"&gt;correlation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;100"&lt;/span&gt;
    &lt;span class="na"&gt;jitter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0ms"&lt;/span&gt;
  &lt;span class="na"&gt;duration&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;5m"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Experiment 2: Testing Security Controls During Resource Exhaustion&lt;/strong&gt;&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;litmuschaos.io/v1alpha1&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;ChaosEngine&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;memory-stress-security-test&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;appinfo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;appns&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;
    &lt;span class="na"&gt;applabel&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;app=vulnerable-app'&lt;/span&gt;
    &lt;span class="na"&gt;appkind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;deployment'&lt;/span&gt;
  &lt;span class="na"&gt;chaosServiceAccount&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;litmus-admin&lt;/span&gt;
  &lt;span class="na"&gt;experiments&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;pod-memory-hog&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;components&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;env&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;MEMORY_CONSUMPTION&lt;/span&gt;
          &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;500'&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;TOTAL_CHAOS_DURATION&lt;/span&gt;
          &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;300'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Monitor and Observe
&lt;/h3&gt;

&lt;p&gt;While the chaos experiments run, we monitor several security metrics:&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;# Monitor KubeArmor alerts&lt;/span&gt;
kubectl logs &lt;span class="nt"&gt;-n&lt;/span&gt; kubearmor &lt;span class="nt"&gt;-l&lt;/span&gt; kubearmor-app&lt;span class="o"&gt;=&lt;/span&gt;kubearmor &lt;span class="nt"&gt;--tail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;100 &lt;span class="nt"&gt;-f&lt;/span&gt;

&lt;span class="c"&gt;# Check for privilege escalation attempts&lt;/span&gt;
kubectl get events &lt;span class="nt"&gt;--field-selector&lt;/span&gt; &lt;span class="nv"&gt;reason&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;FailedMount,reason&lt;span class="o"&gt;=&lt;/span&gt;SecurityContextDeny

&lt;span class="c"&gt;# Monitor network policies&lt;/span&gt;
kubectl describe networkpolicies
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What We Learn from Breaking Things
&lt;/h2&gt;

&lt;p&gt;Running these experiments consistently reveals patterns that traditional security testing misses:&lt;/p&gt;

&lt;h3&gt;
  
  
  Discovery 1: Security Controls Fail Under Load
&lt;/h3&gt;

&lt;p&gt;In one experiment, I discovered that our API rate limiting completely broke down when pods were under memory pressure. The security control was there, but it became ineffective when the system was stressed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Discovery 2: Network Policies Have Edge Cases
&lt;/h3&gt;

&lt;p&gt;During a network partition experiment, we found that certain pod-to-pod communications bypassed our network policies when DNS resolution was flaky. This created an unexpected attack vector.&lt;/p&gt;

&lt;h3&gt;
  
  
  Discovery 3: Monitoring Blind Spots
&lt;/h3&gt;

&lt;p&gt;Chaos experiments revealed that our security monitoring had significant blind spots during high-CPU usage periods. Critical security events were being dropped or delayed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Practices for Security Chaos Engineering
&lt;/h2&gt;

&lt;p&gt;Based on my experience implementing this across different organizations, here are key practices that work:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Start Small&lt;/strong&gt;: Begin with non-production environments and simple experiments. Don't try to simulate a full-scale attack on day one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hypothesis-Driven&lt;/strong&gt;: Each experiment should test a specific security assumption. "What happens to our authentication system when the database is slow?" is better than "let's see what breaks."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Automate Everything&lt;/strong&gt;: Manual chaos is not sustainable. Use tools like ChaosMesh and LitmusChaos to create repeatable, scheduled experiments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Learn and Iterate&lt;/strong&gt;: Each experiment should lead to concrete improvements in your security posture. If you're not fixing things you discover, you're not doing it right.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build Observability First&lt;/strong&gt;: You can't understand what breaks if you can't see it breaking. Ensure comprehensive monitoring and logging before running experiments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Collaborate Across Teams&lt;/strong&gt;: Security chaos engineering works best when security, development, and operations teams work together. Each brings unique perspectives on what might break.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools of the Trade
&lt;/h2&gt;

&lt;p&gt;Here's my current toolkit for Security Chaos Engineering:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ChaosMesh&lt;/strong&gt;: Excellent for Kubernetes-native chaos experiments with good security experiment support&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LitmusChaos&lt;/strong&gt;: Great for complex, multi-step chaos workflows&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;KubeArmor&lt;/strong&gt;: Runtime security monitoring that integrates well with chaos experiments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Falco&lt;/strong&gt;: For detecting unusual behavior during experiments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gremlin&lt;/strong&gt;: Commercial option with advanced security testing features&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Mindset Shift
&lt;/h2&gt;

&lt;p&gt;The biggest challenge isn't technical – it's cultural. Organizations need to shift from "don't break production" to "break production safely and learn from it."&lt;/p&gt;

&lt;p&gt;This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Embracing failure&lt;/strong&gt; as a learning opportunity&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Questioning assumptions&lt;/strong&gt; about security controls regularly
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Building systems&lt;/strong&gt; that are resilient to both accidental and malicious failures&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Investing time&lt;/strong&gt; in proactive testing rather than just reactive incident response&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Looking Forward
&lt;/h2&gt;

&lt;p&gt;Security Chaos Engineering is still evolving, but I'm convinced it represents the future of proactive security. As systems become more complex and distributed, our security testing needs to evolve too.&lt;/p&gt;

&lt;p&gt;The goal isn't to replace traditional security practices – it's to complement them. Penetration testing, vulnerability scanning, and compliance audits all have their place. But they're not enough anymore.&lt;/p&gt;

&lt;p&gt;If you're curious to learn more about this approach, I'll be diving deeper into practical implementations and advanced scenarios at the OpenSSF Community Day India. We'll do live demos, explore real-world case studies, and hopefully convince a few more people that breaking things on purpose is actually a pretty good idea.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What's your experience with chaos engineering? Have you tried applying it to security? I'd love to hear your thoughts and experiences. Feel free to reach out – the security community gets stronger when we share our learnings, especially our failures.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>kubernetes</category>
      <category>devops</category>
    </item>
    <item>
      <title>Google's Gemini CLI: Open Source AI Agent</title>
      <dc:creator>Pratik Mahalle</dc:creator>
      <pubDate>Fri, 04 Jul 2025 17:16:05 +0000</pubDate>
      <link>https://dev.to/pratikmahalle/googles-gemini-cli-open-source-ai-agent-5533</link>
      <guid>https://dev.to/pratikmahalle/googles-gemini-cli-open-source-ai-agent-5533</guid>
      <description>&lt;p&gt;Hey everyone! So I just got my hands on Google's brand new Gemini CLI, and I'm honestly blown away. This isn't just another AI tool – it's a complete game-changer that brings the power of Gemini 2.5 Pro directly into your terminal. Let me tell you why this has me so excited.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Makes This Different?
&lt;/h2&gt;

&lt;p&gt;Google describes Gemini CLI as "an open-source AI agent that brings the power of Gemini directly into your terminal" – and that's exactly what it does. But here's what really caught my attention: it can handle over 1 million tokens in context, making it easy to analyze large projects. &lt;/p&gt;

&lt;p&gt;Think about that for a second. Most AI tools struggle with large codebases, but this thing can literally understand your entire project at once. It's like having a senior developer who's read through every single file in your repo and can give you contextual advice about any part of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Setup Is Surprisingly Smooth
&lt;/h2&gt;

&lt;p&gt;I was expecting the usual developer tool setup nightmare, but Google actually made this dead simple. You've got two options:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 1: Try it instantly&lt;/strong&gt; (no installation needed):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx https://github.com/google-gemini/gemini-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Option 2: Install it globally&lt;/strong&gt; (recommended):&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="nb"&gt;sudo &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @google/gemini-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it! Just make sure you have Node.js 18 or later, and you're good to go. Once installed, just type &lt;code&gt;gemini&lt;/code&gt; in your terminal and boom – you're in.&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%2Fc6bnhyhty4wmou3zjln4.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%2Fc6bnhyhty4wmou3zjln4.png" alt="Gemini Code Block" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Free Tier Is Actually Insane
&lt;/h2&gt;

&lt;p&gt;Here's where Google really surprised me. They're offering "the industry's largest allowance: 60 model requests per minute and 1,000 requests per day at no charge". Let me put that in perspective – that's more than most developers would ever need, and it's completely free if you just log in with your Google account.&lt;/p&gt;

&lt;p&gt;Compare that to other AI tools where you hit limits after a few conversations. This is a legitimate free tier that you can actually rely on for real work.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Multimodal Magic
&lt;/h2&gt;

&lt;p&gt;Now here's where things get really interesting. Gemini CLI has "multimodal app prototyping" capabilities and can "quickly generate app prototypes from PDFs or sketches". &lt;/p&gt;

&lt;p&gt;I tested this by uploading a rough sketch of a UI mockup, and it generated working HTML/CSS code that actually looked like what I drew. The AI can literally see your images, understand your drawings, and turn them into code. It's like having a designer and developer rolled into one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Built-in Superpowers
&lt;/h2&gt;

&lt;p&gt;The tool comes packed with features that make it feel like a proper AI assistant rather than just a chatbot:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Google Search Integration&lt;/strong&gt;: It can "ground prompts with Google Search so you can fetch web pages and provide real-time, external context to the model". No more outdated information – it pulls fresh data from the web.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;File Upload with @&lt;/strong&gt;: Just type &lt;code&gt;@&lt;/code&gt; in the CLI and it opens a file picker. You can upload code, images, documents – whatever you need the AI to analyze.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DevOps Automation&lt;/strong&gt;: It can "perform Git operations, fetch PRs, create migration plans, and more". I've already used it to generate complex git commands I always forget.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creative Content Generation&lt;/strong&gt;: It has "tool integration" that can "connect to media generation models like Imagen, Veo, and Lyria" for creating images and videos.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Testing Results
&lt;/h2&gt;

&lt;p&gt;I've been using this for about a week now, and here are some scenarios where it absolutely shines:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Analysis&lt;/strong&gt;: I uploaded a legacy Python project with 50+ files. Within seconds, it understood the entire codebase and could explain complex functions, suggest improvements, and even identify potential bugs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Debugging&lt;/strong&gt;: Instead of copying error messages to Google, I just paste them directly into the CLI. It not only explains what's wrong but provides contextual fixes based on my actual code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Learning New Frameworks&lt;/strong&gt;: I'm picking up React, and this thing has been like having a personal tutor. It explains concepts, shows examples, and even generates starter code that follows best practices.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Command Line Wizardry&lt;/strong&gt;: Forgot that complex Docker command? Need a specific git workflow? The AI remembers everything and can generate exactly what you need.&lt;/p&gt;

&lt;h2&gt;
  
  
  The VSCode Integration Is Seamless
&lt;/h2&gt;

&lt;p&gt;Here's something cool – Google has integrated Gemini CLI with their "Gemini Code Assist" so that "all developers — on free, Standard, and Enterprise Code Assist plans — get prompt-driven, AI-first coding in both VS Code and Gemini CLI".&lt;/p&gt;

&lt;p&gt;You can literally run &lt;code&gt;gemini&lt;/code&gt; right inside VSCode's integrated terminal and use the same &lt;code&gt;@&lt;/code&gt; command to select files from your current project. It's like having the best of both worlds – the power of the terminal with the convenience of your IDE.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open Source Means Real Freedom
&lt;/h2&gt;

&lt;p&gt;The entire project is "fully open source (Apache 2.0)", which means you can actually inspect the code, understand how it works, and contribute improvements. This isn't a black box – you can see exactly what's happening with your data.&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%2F7ot6hnkqrfm1z6s3ep4j.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%2F7ot6hnkqrfm1z6s3ep4j.png" alt="Open Source" width="800" height="195"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Google is actively encouraging community contributions, and I expect we'll see some amazing extensions and improvements from the developer community soon.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Feels Like the Future
&lt;/h2&gt;

&lt;p&gt;Using Gemini CLI feels fundamentally different from other AI tools. It's not just about asking questions – it's about having an AI that truly understands your development context and can take action within your workflow.&lt;/p&gt;

&lt;p&gt;The massive "1 million token context window" means it can keep track of complex conversations, understand large codebases, and maintain context across multiple interactions. It's like having a coding partner who never forgets anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Enterprise Story
&lt;/h2&gt;

&lt;p&gt;If you're working in a team or enterprise environment, you can use "a Google AI Studio or Vertex AI key for usage-based billing or get a Gemini Code Assist Standard or Enterprise license". This gives you higher rate limits and enterprise-grade features.&lt;/p&gt;

&lt;p&gt;But honestly, for most individual developers, the free tier is more than enough to get started and see real productivity gains.&lt;/p&gt;

&lt;h2&gt;
  
  
  Should You Try It Right Now?
&lt;/h2&gt;

&lt;p&gt;Absolutely. This tool has genuinely changed how I approach coding. The setup takes 5 minutes, it's completely free, and it might just revolutionize your development workflow.&lt;/p&gt;

&lt;p&gt;What impressed me most is how natural the interaction feels. You're not fighting with a clunky web interface or waiting for pages to load. Everything happens instantly in your familiar terminal environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started Today
&lt;/h2&gt;

&lt;p&gt;Ready to give it a shot? Here's what you need to do:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make sure you have Node.js 18+ installed&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;sudo npm install -g @google/gemini-cli&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Type &lt;code&gt;gemini&lt;/code&gt; in your terminal&lt;/li&gt;
&lt;li&gt;Choose your theme and sign in with Google&lt;/li&gt;
&lt;li&gt;Start experimenting!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first time you run it, it'll walk you through the setup process. Choose "Login with Google" for the best free experience, and you'll be up and running in under 5 minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Google's Gemini CLI isn't just another AI tool – it's a fundamental shift in how we interact with AI while coding. It brings enterprise-grade AI capabilities directly into the environment where developers actually work, with generous free limits that make it accessible to everyone.&lt;/p&gt;

&lt;p&gt;The combination of massive context windows, multimodal capabilities, web search integration, and seamless workflow integration makes this feel like the AI assistant we've all been waiting for.&lt;/p&gt;

&lt;p&gt;If you're a developer, this is definitely worth your time. Your terminal is about to get a whole lot smarter, and your productivity is about to take a serious jump.&lt;/p&gt;

&lt;p&gt;Trust me on this one – give it a try today. You'll wonder how you ever coded without it. That`s it for now, see you in another one. If you have to talk more about it, you can connect with me on &lt;a href="https://x.com/pratikstwts" rel="noopener noreferrer"&gt;x&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>gemini</category>
      <category>ai</category>
      <category>google</category>
      <category>opensource</category>
    </item>
    <item>
      <title>KEDA: Smarter Scaling for Kubernetes – Event-Driven and Effortless</title>
      <dc:creator>Pratik Mahalle</dc:creator>
      <pubDate>Sun, 29 Jun 2025 09:47:54 +0000</pubDate>
      <link>https://dev.to/pratikmahalle/keda-smarter-scaling-for-kubernetes-event-driven-and-effortless-6a8</link>
      <guid>https://dev.to/pratikmahalle/keda-smarter-scaling-for-kubernetes-event-driven-and-effortless-6a8</guid>
      <description>&lt;p&gt;I was just exploring some CNCF projects and then I got to know about Keda. So, in this article, we will be talking about Kubernetes Event-driven Autoscaling (KEDA). &lt;/p&gt;

&lt;p&gt;Scaling applications in Kubernetes is pretty cool, right? But what if I told you there’s a smarter way to scale — not just based on CPU or memory, but based on real-world events like incoming messages, pending jobs, or HTTP requests?&lt;/p&gt;

&lt;p&gt;Let me introduce you to KEDA — Kubernetes Event-Driven Autoscaler.&lt;/p&gt;

&lt;p&gt;Whether you’re new to Kubernetes or someone who's been running clusters for a while, you’ll love how KEDA changes the way we think about autoscaling.&lt;/p&gt;

&lt;p&gt;KEDA was accepted to CNCF on March 12, 2020, moved to the Incubating maturity level on August 18, 2021, and then moved to the Graduated maturity level on August 22, 2023. &lt;/p&gt;

&lt;h4&gt;
  
  
  The Challenge with Traditional Autoscaling
&lt;/h4&gt;

&lt;p&gt;So, imagine this: you’ve set up your application to scale with HPA, which primarily focuses on CPU and memory usage. That’s great for CPU-heavy apps, but what about those applications that don’t rely solely on these metrics for performance?&lt;br&gt;
Think of apps that process message queues, listen to streaming events (like Kafka), or handle background jobs based on database records. Often, these apps can have a large backlog of tasks while their CPU is barely hitting 10%. Frustrating, right?&lt;/p&gt;

&lt;p&gt;In Kubernetes, we usually scale our apps with the Horizontal Pod Autoscaler (HPA).&lt;br&gt;
But here’s the thing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HPA mostly cares about CPU and memory usage.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s fine if your app is CPU-heavy. But what if your app:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;    Processes a message queue?&lt;/li&gt;
&lt;li&gt;    Listens for events from a streaming platform like Kafka?&lt;/li&gt;
&lt;li&gt;    Runs background jobs based on database records?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In these cases, CPU and memory aren’t always the right signals to decide whether to scale up or down.&lt;br&gt;
You could have a huge backlog of work, but the CPU is chilling at 10%.&lt;/p&gt;

&lt;p&gt;This is where KEDA comes in.&lt;/p&gt;

&lt;h4&gt;
  
  
  Enter KEDA
&lt;/h4&gt;

&lt;p&gt;This is where KEDA comes to the rescue. It’s an open-source project that allows you to scale your Kubernetes applications based on the number of messages in a queue, the rate of events, or other custom metrics. It empowers us to scale our workloads dynamically and efficiently, depending on specific triggers and workloads rather than just CPU or memory.&lt;/p&gt;

&lt;h4&gt;
  
  
  How Does KEDA Work?
&lt;/h4&gt;

&lt;p&gt;KEDA works by using a set of scalers—these are components that listen to various events and determine when and how much to scale your applications. It integrates seamlessly with existing tools like HPA, allowing it to use the scaling logic of Kubernetes, but with the added finesse of reacting to specific event-driven conditions.&lt;/p&gt;

&lt;p&gt;Here’s how it typically functions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scaler Configuration&lt;/strong&gt;: You define which event source (like a Kafka queue or Azure Queue Storage) KEDA should monitor and specify the scaling logic within a Custom Resource Definition (CRD).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Event Monitoring&lt;/strong&gt;: KEDA continuously watches the specified external event sources. For instance, if you set it to monitor a message queue, it will check how many messages are in the queue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Autoscaling&lt;/strong&gt;: When the defined threshold is reached—say, the number of messages exceeds a certain value—KEDA triggers the HPA to scale up the pods. If the backlog decreases (or if the queue is empty), it will scale down accordingly.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Why KEDA is Worth Using
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Flexibility&lt;/strong&gt;: KEDA supports a wide range of event sources, from message queues to databases and custom metrics, making it adaptable for various use cases.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cost-Efficiency&lt;/strong&gt;: By scaling your application based on actual demand (number of events, messages, etc.), you’re only using the resources you need, potentially reducing costs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Simplicity&lt;/strong&gt;: The setup is relatively straightforward, especially if you're already familiar with Kubernetes. With KEDA's CRDs, you can quickly get started integrating advanced autoscaling capabilities.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Real-World Use Cases
&lt;/h4&gt;

&lt;p&gt;Let’s take a look at how KEDA can shine in real-life situations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Background Jobs&lt;/strong&gt;: If you have a system that processes data in batches (think image processing), KEDA can scale your worker pods based on the number of images waiting to be processed in a queue.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Event Stream Processing&lt;/strong&gt;: If you're capturing events from a data streaming platform like Kafka, KEDA can monitor the number of unprocessed events and scale your consumers up or down accordingly, ensuring that no event is left hanging.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Microservice Communication&lt;/strong&gt;: In a microservices architecture, certain services may only need to scale based on specific triggers, such as the number of requests or messages from another service. KEDA can handle this beautifully.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Refer this for more
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;    &lt;a href="https://keda.sh/docs/2.17/deploy/" rel="noopener noreferrer"&gt;KEDA Official Docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;    &lt;a href="https://github.com/kedacore/keda" rel="noopener noreferrer"&gt;KEDA GitHub Repository&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;    &lt;a href="https://keda.sh/blog" rel="noopener noreferrer"&gt;KEDA Blogs&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Conclusion
&lt;/h4&gt;

&lt;p&gt;If you’re looking to optimize your Kubernetes applications and enhance their autoscaling capabilities, KEDA is definitely worth giving a try. It helps bridge the gap between traditional scaling methods and the dynamic workloads that today’s applications often require. &lt;/p&gt;

&lt;p&gt;Let me know if you end up experimenting with KEDA. I’d love to hear about your experiences or any challenges you encounter along the way! If you have any suggestion, you can connect me on &lt;a href="https://x.com/pratikstwts" rel="noopener noreferrer"&gt;x&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Happy scaling! 🍻&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>opensource</category>
    </item>
    <item>
      <title>🐣How to Save Money with AWS Spot Instances</title>
      <dc:creator>Pratik Mahalle</dc:creator>
      <pubDate>Tue, 20 May 2025 05:53:55 +0000</pubDate>
      <link>https://dev.to/aws-builders/how-to-save-money-with-aws-spot-instances-171n</link>
      <guid>https://dev.to/aws-builders/how-to-save-money-with-aws-spot-instances-171n</guid>
      <description>&lt;p&gt;What if I told you that you can reduce your cloud costs by up to 90%—without rewriting your application? Yes, that’s what Spot Instances are for.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Exactly is a Spot Instance?&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To understand Spot Instances, Lets consider a scene, think of AWS like an airline. Sometimes, seats go unsold, and the airlines offer those seats at lower prices due to unsold capacity. Spot Instances are AWS’s unsold capacity sold at a discount.&lt;/p&gt;

&lt;p&gt;Spot Instances are essentially the same as regular EC2 Instances, but they are significantly cheaper because you are using AWS's extra, unused servers. The probelm is that these instances can be taken away at any time. However, don’t worry; it’s not as scary as it sounds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When Should You Use Spot Instances?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So, when should you use a Spot Instance for your application, Right?&lt;br&gt;
 Spot Instances are amazing, but they are not right for everyone. Here are some scenarios where using them makes sense:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Development and Test Environments:&lt;/strong&gt; Use Spot Instances for developing and testing applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CI/CD Pipelines:&lt;/strong&gt; Run build and test jobs cost-effectively, mainly for open-source.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Batch Jobs:&lt;/strong&gt; Execute batch processing jobs at lower costs, particularly for open-source or internal applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Containers with Fargate or ECS:&lt;/strong&gt; If you are using containers, Spot Instances can be a smart way to save costs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👋 &lt;strong&gt;One Last Thing:&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Using Spot Instances is not just about saving money; it also encourages to think about scalability, resilience, and automation—core skills for any solution architect or DevOps engineer. If you have time, try creating a Spot Instance to see how it work, and then imagine replacing ten of your servers with it. &lt;/p&gt;

&lt;p&gt;If you want to know more, you can check the references below.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Spot Instance Pricing Page&lt;/li&gt;
&lt;li&gt;EC2 Spot vs. On-Demand Explained (AWS Docs)&lt;/li&gt;
&lt;li&gt;YouTube: Spot Instances in Production – Good Idea?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That`s it for this now! I'm happy you made it to the end - thank you so much for your support. If you have any queries or opinions, you can connect with me on x.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>contentwriting</category>
      <category>cloud</category>
    </item>
    <item>
      <title>A Beginner's Journey: Deploying Applications on Amazon EKS</title>
      <dc:creator>Pratik Mahalle</dc:creator>
      <pubDate>Thu, 17 Apr 2025 10:17:36 +0000</pubDate>
      <link>https://dev.to/aws-builders/a-beginners-journey-deploying-applications-on-amazon-eks-2004</link>
      <guid>https://dev.to/aws-builders/a-beginners-journey-deploying-applications-on-amazon-eks-2004</guid>
      <description>&lt;p&gt;In this blog post, I want to walk you through the step-by-step process of deploying a straightforward web application utilising Amazon EKS (Elastic Kubernetes Service). &lt;br&gt;
Kubernetes has emerged as one of the most widely adopted tools in the DevOps industry. However, many individuals find themselves wrestling with the complexities of EKS and its integration with AWS. My objective is to demonstrate these concepts, making them more accessible and practical for implementation.&lt;/p&gt;
&lt;h2&gt;
  
  
  What Is Kubernetes?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://kubernetes.io/" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt; is an innovative open-source platform designed for container orchestration. It automates critical processes such as deploying, scaling, and managing containerised applications.&lt;br&gt;
Originally developed by Google, Kubernetes is now watched by the Cloud Native Computing Foundation. In essence, Kubernetes serves as a powerful framework for managing your applications, enabling seamless deployment and scalability tailored to your needs.&lt;/p&gt;
&lt;h3&gt;
  
  
  Why EKS?
&lt;/h3&gt;

&lt;p&gt;When it comes to deploying and managing the containerised application, Elastic Kubernetes Service stand out exceptionally well. Here's why EKS can transform your deployment strategy.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Fully Managed&lt;/strong&gt;: EKS simplifies Kubernetes management by handling tasks like deploying and scaling, allowing your team to focus on building exceptional applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Seamless AWS Integration&lt;/strong&gt;: EKS works effortlessly with AWS services, improving your application's functionality while maintaining strong security through IAM and other tools.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic Scalability&lt;/strong&gt;: It easily adjusts the number of nodes and pods to match traffic demands, ensuring efficient resource utilisation and potential cost savings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High Availability&lt;/strong&gt;: Leveraging multiple Availability Zones(AZ), EKS guarantees that your applications remain online and available, even during unexpected challenges.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhanced Security&lt;/strong&gt;: With built-in security features like IAM integration and automatic data encryption, EKS safeguards your sensitive information.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Strong Support Community&lt;/strong&gt;: EKS has among the strong community support concerning others as it gives you access to best practices and assistance whenever needed.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  How Do We Deploy Cloud-Native Apps on EKS?
&lt;/h2&gt;

&lt;p&gt;This tutorial's primary goal is to demonstrate how to deploy a containerised application onto an EKS cluster, leveraging Helm for efficient package management.&lt;/p&gt;
&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;Before diving into the deployment process, this is the deployment process we are going to use and ensure you have the following tools installed and configured on your system:&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%2Fkhllmqaf0uerbs0a6k76.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%2Fkhllmqaf0uerbs0a6k76.png" alt="Architecture diagram" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Python&lt;/strong&gt;: A powerful programming language necessary for application development.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt;&lt;/strong&gt;: A platform for developing, shipping, and running applications in containers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://kubernetes.io/" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt;&lt;/strong&gt;: The container orchestration system we'll be working with.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://helm.sh/" rel="noopener noreferrer"&gt;Helm&lt;/a&gt;&lt;/strong&gt;: The package manager for Kubernetes that simplifies deployment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://aws.amazon.com/cli/" rel="noopener noreferrer"&gt;AWS CLI&lt;/a&gt;&lt;/strong&gt;: Command Line Interface for interacting with AWS services.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://aws.amazon.com/eks/" rel="noopener noreferrer"&gt;Amazon EKS&lt;/a&gt;&lt;/strong&gt;: AWS's managed Kubernetes service.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To access the source code and additional resources, feel free to visit the GitHub repository here: [GitHub Repo Link: &lt;a href="https://github.com/pratik-mahalle/Zero-to-Production" rel="noopener noreferrer"&gt;https://github.com/pratik-mahalle/Zero-to-Production&lt;/a&gt;].&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 1: Dockerizing the Application
&lt;/h2&gt;

&lt;p&gt;Let's picture you have a simple application written in Python. The first crucial step involves creating a Docker image of this application. Below is the Dockerfile that I used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; python:3.9-slim&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 5000&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["python", "app.py"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this Dockerfile:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We start from the official Python 3.9 image with a slim footprint to keep our container lightweight.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;WORKDIR&lt;/code&gt; instruction sets the working directory in the container to &lt;code&gt;/app&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;All application files are copied into this directory.&lt;/li&gt;
&lt;li&gt;The command &lt;code&gt;pip install -r requirements.txt&lt;/code&gt; installs all necessary dependencies.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;EXPOSE&lt;/code&gt; command tells Docker to expose port 5000 on the container for web traffic.&lt;/li&gt;
&lt;li&gt;Finally, the &lt;code&gt;CMD&lt;/code&gt; instruction specifies how to run the application.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Next, we will upload this Docker image to an Amazon ECR (Elastic Container Registry). Ensure that you create an ECR repository through the AWS Console and authenticate your Docker client for the process.&lt;/p&gt;

&lt;p&gt;To obtain an authentication token and log in to your Docker registry, execute the following command in the AWS CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ecr get-login-password - region ap-south-1 | docker login - username AWS - password-stdin &lt;span class="o"&gt;[&lt;/span&gt;AWS_ACCOUNT_ID].dkr.ecr.ap-south-1.amazonaws.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Important Note:&lt;/strong&gt; If you encounter any issues when using the AWS CLI, check that you have the latest versions of both the AWS CLI and Docker installed. Make sure to replace the AWS_ACCOUNT_ID with your actual AWS account id.&lt;/p&gt;

&lt;p&gt;Now, to build your Docker image, use the following command. If further information on building a Docker image from scratch is needed, please refer to &lt;a href="https://docs.docker.com/get-started/introduction/build-and-push-first-image/" rel="noopener noreferrer"&gt;this resource&lt;/a&gt;. You can skip this if your image is already built:&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; demo .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the build is complete, it's crucial to tag the image to prepare it for pushing to your ECR repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker tag demo:latest &lt;span class="o"&gt;[&lt;/span&gt;AWS_ACCOUNT_ID].dkr.ecr.ap-south-1.amazonaws.com/demo:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, push your Docker image to the AWS repository with this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker push &lt;span class="o"&gt;[&lt;/span&gt;AWS_ACCOUNT_ID].dkr.ecr.ap-south-1.amazonaws.com/demo:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congratulations! Your application is now successfully dockerized and ready for deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Create an EKS Cluster
&lt;/h2&gt;

&lt;p&gt;With your application dockerized, the next step is to create an EKS cluster. First, verify that you have the AWS CLI, &lt;code&gt;kubectl&lt;/code&gt;, and &lt;code&gt;eksctl&lt;/code&gt; installed and properly configured on your terminal.&lt;/p&gt;

&lt;p&gt;To create an EKS cluster, execute the following command in the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;eksctl create cluster - name demo-cluster - region ap-south-1 - nodes 1 - spot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Note: I opted for a spot instance since I plan to use this cluster for an extended period, which can be more cost-effective.)&lt;/p&gt;

&lt;p&gt;After the cluster is created, it's crucial to update your kubeconfig file to ensure you're working with the latest resource configurations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws eks update-kubeconfig - name demo-cluster
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To enable your pods to securely access AWS services without the need to store long-term credentials, we will configure a service account with appropriate IAM roles.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Create an OIDC Provider for Your EKS Cluster(Optional but recommended)
&lt;/h3&gt;

&lt;p&gt;Run the following command to set up an OpenID Connect (OIDC) provider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;eksctl utils associate-iam-oidc-provider - region ap-south-1 - cluster demo-cluster - approve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Create an IAM Policy for ECR Access
&lt;/h3&gt;

&lt;p&gt;Creating an IAM policy can be done via the AWS Console. Below is an example policy you can use, which grants the necessary permissions for ECR:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012–10–17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"VisualEditor0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ecr:DescribeImageScanFindings"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ecr:StartImageScan"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ecr:GetLifecyclePolicyPreview"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ecr:CreateRepository"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ecr:PutImageScanningConfiguration"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ecr:GetAuthorizationToken"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ecr:UpdateRepositoryCreationTemplate"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ecr:PutRegistryScanningConfiguration"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ecr:ListImages"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ecr:GetRegistryScanningConfiguration"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ecr:BatchGetImage"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ecr:ReplicateImage"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ecr:GetLifecyclePolicy"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As a best practice, always attach the least privileged policy to enhance security measures.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Create the IAM Role with IRSA Binding
&lt;/h3&gt;

&lt;p&gt;To create the IAM service account, execute the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;eksctl create iamserviceaccount &lt;span class="se"&gt;\&lt;/span&gt;
 - name ecr-access-sa &lt;span class="se"&gt;\&lt;/span&gt;
 - namespace default &lt;span class="se"&gt;\&lt;/span&gt;
 - cluster demo-cluster &lt;span class="se"&gt;\&lt;/span&gt;
 - attach-policy-arn arn:aws:iam::[AWS_ACCOUNT_ID]:policy/ECRReadAccess &lt;span class="se"&gt;\&lt;/span&gt;
 - approve &lt;span class="se"&gt;\&lt;/span&gt;
 - override-existing-serviceaccounts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your EKS cluster is now adequately configured and ready for application deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Deploy Your Application
&lt;/h2&gt;

&lt;p&gt;In the next section, we will delve into the details of registering our application with the EKS cluster and employing Kubernetes resources to manage and expose our application effectively.&lt;br&gt;
Now, you're ready to deploy your app!&lt;/p&gt;

&lt;p&gt;Here is the basic Helm structure of the app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flask-app/
├── Chart.yaml
├── templates/
│ ├── deployment.yaml
│ └── service.yaml
└── values.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's write the &lt;code&gt;values.yaml&lt;/code&gt; file. This file will store all the configuration values.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;replicaCount: 2
image:
 repository: _.dkr.ecr.ap-south-1.amazonaws.com/demo
 tag: latest
 pullPolicy: IfNotPresent
service:
 type: LoadBalancer
 port: 80
 targetPort: 5000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are mapping the external port 80 to app`s internal port 5000 and exposing using thee LoadBalancer. Make sure to replace the repository.&lt;/p&gt;

&lt;h3&gt;
  
  
  Chart.yaml
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;apiVersion: v2&lt;br&gt;
name: flask-app&lt;br&gt;
version: 0.1.0&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Deployment.yaml
&lt;/h3&gt;

&lt;p&gt;Here's your main deployment file which manages the replica set and the desired pods are running:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;apiVersion: apps/v1&lt;br&gt;
kind: Deployment&lt;br&gt;
metadata:&lt;br&gt;
 name: {{ .Chart.Name }}&lt;br&gt;
spec:&lt;br&gt;
 serviceAccountName: ecr-access-sa&lt;br&gt;
 replicas: {{ .Values.replicaCount }}&lt;br&gt;
 selector:&lt;br&gt;
 matchLabels:&lt;br&gt;
 app: {{ .Chart.Name }}&lt;br&gt;
 template:&lt;br&gt;
 metadata:&lt;br&gt;
 labels:&lt;br&gt;
 app: {{ .Chart.Name }}&lt;br&gt;
 spec:&lt;br&gt;
 containers:&lt;br&gt;
 - name: {{ .Chart.Name }}&lt;br&gt;
 image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"&lt;br&gt;
 ports:&lt;br&gt;
 - containerPort: {{ .Values.service.targetPort }}&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It uses the values from the values.yaml.&lt;/p&gt;

&lt;h3&gt;
  
  
  Service.yaml
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;apiVersion: v1&lt;br&gt;
kind: Service&lt;br&gt;
metadata:&lt;br&gt;
 name: {{ .Chart.Name }}&lt;br&gt;
spec:&lt;br&gt;
 type: {{ .Values.service.type }}&lt;br&gt;
 selector:&lt;br&gt;
 app: {{ .Chart.Name }}&lt;br&gt;
 ports:&lt;br&gt;
 - name: http&lt;br&gt;
 protocol: TCP&lt;br&gt;
 port: 80 &lt;br&gt;
 targetPort: 5000&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We are exposing the application on port 80 using a LoadBalancer.&lt;br&gt;
Now we are done with the Helm configuration. To deploy our app using Helm, use the following command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;helm upgrade - install flask-app ./Zero-to-Production - namespace default&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To access your application, run:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;kubectl get svc flask-app&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then copy the &lt;strong&gt;external IP&lt;/strong&gt; and paste it into your browser. And that`s it, you did it!&lt;/p&gt;

&lt;h3&gt;
  
  
  Additional Information
&lt;/h3&gt;

&lt;p&gt;You can use horizontal pod autoscaling (hpa) to scale the app in case of increased traffic, or you can simply use the &lt;code&gt;kubectl scale&lt;/code&gt; command to scale the application. you can check the github repo for the scaling the pods.&lt;/p&gt;

&lt;p&gt;That`s it for this now! I'm happy you made it to the end - thank you so much for your support. If you have any queries or opinions, you can connect with me on &lt;a href="https://x.com/PratikMahalle10" rel="noopener noreferrer"&gt;x&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>kubernetes</category>
      <category>aws</category>
      <category>docker</category>
    </item>
  </channel>
</rss>
