<?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: Kamesh Sampath</title>
    <description>The latest articles on DEV Community by Kamesh Sampath (@kameshsampath).</description>
    <link>https://dev.to/kameshsampath</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F871628%2F0eb1f610-f2c7-4371-a6b3-d8c7fcf9123b.jpg</url>
      <title>DEV Community: Kamesh Sampath</title>
      <link>https://dev.to/kameshsampath</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kameshsampath"/>
    <language>en</language>
    <item>
      <title>Teaching Agents When Not to Act: Agentic DevOps with Snowflake CoCo</title>
      <dc:creator>Kamesh Sampath</dc:creator>
      <pubDate>Fri, 03 Jul 2026 06:17:16 +0000</pubDate>
      <link>https://dev.to/kameshsampath/teaching-agents-when-not-to-act-agentic-devops-with-snowflake-coco-d6d</link>
      <guid>https://dev.to/kameshsampath/teaching-agents-when-not-to-act-agentic-devops-with-snowflake-coco-d6d</guid>
      <description>&lt;p&gt;&lt;em&gt;Why the future of DevOps isn’t just about what AI can do, but what it’s authorized to do.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6r95wnr81dj2oi1vvv90.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6r95wnr81dj2oi1vvv90.png" alt="Future of DevOps" width="800" height="534"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Agentic DevOps is not about teaching agents to act faster. It is about teaching them when not to act.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Like most engineers, I’ve had moments where I trusted automation a little more than I should have.&lt;/p&gt;

&lt;p&gt;One of those moments came when I set up an auto-fix bot for a CI pipeline.&lt;/p&gt;

&lt;p&gt;It found a race condition and “fixed” it by removing the lock. The deadlock that followed made its way into production and surfaced at 2am on a Friday.&lt;/p&gt;

&lt;p&gt;The AI wasn’t really the problem. It did exactly what I asked it to do.&lt;/p&gt;

&lt;p&gt;The problem was that I never defined what a safe fix looked like.&lt;/p&gt;

&lt;p&gt;And the agent had no way to challenge that assumption.&lt;/p&gt;
&lt;h3&gt;
  
  
  AI-assisted DevOps is not Agentic DevOps
&lt;/h3&gt;

&lt;p&gt;People use “AI-assisted DevOps” and “Agentic DevOps” interchangeably.&lt;/p&gt;

&lt;p&gt;They are not the same thing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI-assisted DevOps&lt;/strong&gt; is a text generator with a human execution layer.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Copilot suggests. You run.&lt;/li&gt;
&lt;li&gt;Claude Code proposes. You accept.&lt;/li&gt;
&lt;li&gt;The agent generates. The human ships.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Agentic DevOps&lt;/strong&gt; is an execution model.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Agent scaffolds infrastructure.&lt;/li&gt;
&lt;li&gt;Provisions identities.&lt;/li&gt;
&lt;li&gt;Scans code, opens issues, proposes fixes.&lt;/li&gt;
&lt;li&gt;Cleans up when the work is complete.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;You state the outcome. The agent executes the workflow.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is the pattern I have been exploring with&lt;a href="https://www.snowflake.com/en/product/snowflake-coco/" rel="noopener noreferrer"&gt;Snowflake CoCo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;CoCo gives me an AI-native execution layer. The CI/CD workflow described here is an implementation pattern:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use intent to define the desired outcome&lt;/li&gt;
&lt;li&gt;Use policy to define the agent’s authority&lt;/li&gt;
&lt;li&gt;Use human review when the agent is not confident enough to act.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important part is not the repository.&lt;/p&gt;

&lt;p&gt;The important part is the operating model.&lt;/p&gt;
&lt;h3&gt;
  
  
  What changed when I applied IDD to CI/CD
&lt;/h3&gt;

&lt;p&gt;I have written before about &lt;a href="https://blogs.kameshs.dev/intent-driven-development-the-shift-developers-cant-ignore-ef434f94d56c" rel="noopener noreferrer"&gt;Intent-Driven Development&lt;/a&gt;. The idea is simple: structure prompts around outcomes instead of procedural steps.&lt;/p&gt;

&lt;p&gt;The four blocks are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Goal&lt;/li&gt;
&lt;li&gt;Requirements&lt;/li&gt;
&lt;li&gt;Constraints&lt;/li&gt;
&lt;li&gt;Output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The agent figures out how.&lt;/p&gt;

&lt;p&gt;You define the what and the why.&lt;/p&gt;

&lt;p&gt;When I started building this CI scaffold, the scan prompt initially said something like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Find bugs and open issues&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Simple. Direct. Not enough.&lt;/p&gt;

&lt;p&gt;The agent found bugs.&lt;/p&gt;

&lt;p&gt;It opened issues.&lt;/p&gt;

&lt;p&gt;It also tried to auto-fix a 400-line authentication module with high confidence and wrong assumptions.&lt;/p&gt;

&lt;p&gt;The problem was the missing constraint.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Fix my bugs” carries an implicit constraint : “Do it safely.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;IDD forces that constraint into the prompt and the workflow.&lt;/p&gt;

&lt;p&gt;Not as a comment.&lt;/p&gt;

&lt;p&gt;Not as a README note.&lt;/p&gt;

&lt;p&gt;As a policy that the agent reads before acting.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Decision Tree
&lt;/h3&gt;

&lt;p&gt;The constraint became a scoring system.&lt;/p&gt;

&lt;p&gt;Before opening any issue or proposing a fix, the scan agent evaluates three dimensions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SEVERITY&lt;/strong&gt; : how dangerous the issue is if left unfixed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;COMPLEXITY&lt;/strong&gt; : how much the fix touches.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CONFIDENCE&lt;/strong&gt; : how certain the agent is that its fix is correct.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then it routes the issue.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frghph3stjvswrtpfgv7a.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frghph3stjvswrtpfgv7a.png" alt="The governance loop" width="390" height="800"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The governance loop: Mapping an agent’s confidence against its authorized ceiling of action to determine when a human must step in.&lt;/em&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;strong&gt;conservative (default)&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;auto-fix only if severity=low AND complexity=low AND confidence=high everything else -&amp;gt; needs-review&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;strong&gt;aggressive&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;auto-fix if confidence &amp;gt;= medium&lt;/p&gt;
&lt;h4&gt;
  
  
  &lt;strong&gt;off&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;never auto-fix, always needs-review&lt;/p&gt;

&lt;p&gt;This is not a magic rules engine.&lt;/p&gt;

&lt;p&gt;It is a simple judgment model with explicit inputs.&lt;/p&gt;

&lt;p&gt;The race-condition fix from my Friday story would have scored:&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;severity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;high&lt;/span&gt;
&lt;span class="na"&gt;complexity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;high&lt;/span&gt;
&lt;span class="na"&gt;confidence&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;medium&lt;/span&gt;
&lt;span class="na"&gt;route&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;needs-review&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A human would have seen the issue, read the context, and decided whether to run the fix.&lt;/p&gt;

&lt;p&gt;That is the difference I care about.&lt;/p&gt;

&lt;p&gt;An agent that always acts is dangerous.&lt;/p&gt;

&lt;p&gt;An agent that never acts is just autocomplete with a workflow file.&lt;/p&gt;

&lt;p&gt;The useful middle is an agent that can decide when not to act.&lt;/p&gt;

&lt;h3&gt;
  
  
  Intent defines the goal. Policy defines the boundary.
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://blogs.kameshs.dev/infrastructure-as-intent-the-field-velocity-blueprint-e6217ef30f14" rel="noopener noreferrer"&gt;Infrastructure-as-Intent&lt;/a&gt; does not mean the agent gets unlimited freedom.&lt;/p&gt;

&lt;p&gt;It means the desired outcome is expressed clearly enough for the system to act.&lt;/p&gt;

&lt;p&gt;But action still needs a boundary.&lt;/p&gt;

&lt;p&gt;For this workflow, that boundary lives in configuration.&lt;/p&gt;

&lt;p&gt;For example a policy document could be:&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;fix_mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;max_auto&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;conservative&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The intent says what the agent should achieve.&lt;/p&gt;

&lt;p&gt;The policy says how far the agent is allowed to go without human review.&lt;/p&gt;

&lt;p&gt;Change it through a PR.&lt;/p&gt;

&lt;p&gt;The commit history becomes the governance record.&lt;/p&gt;

&lt;p&gt;When your security team asks who allowed the agent to auto-fix beyond low-risk changes, you do not need to reconstruct a Slack thread.&lt;/p&gt;

&lt;p&gt;You show the PR that changed &lt;strong&gt;conservative&lt;/strong&gt; to &lt;strong&gt;aggressive&lt;/strong&gt; , the reviewer, and the merge date.&lt;/p&gt;

&lt;p&gt;That is the record I want Agentic DevOps systems to preserve.&lt;/p&gt;

&lt;p&gt;Not just what the agent did.&lt;/p&gt;

&lt;p&gt;Who allowed it to act at that level.&lt;/p&gt;

&lt;p&gt;For runtime experiments, there can still be a variable override.&lt;/p&gt;

&lt;p&gt;Runtime overrides are necessary, but they introduce drift. Every temporary experiment requires a sunset tag and a hard expiration date. If the override outlives its sprint, the agent must revert to the version-controlled default and trigger a CI alert. This is how we ensure ‘temporary’ hacks don’t calcify into unreviewed permanent policy.&lt;/p&gt;

&lt;p&gt;Maybe the team wants to try aggressive mode for a sprint. Set the variable. When the experiment ends, delete it. The policy falls back to the reviewed default.&lt;/p&gt;

&lt;p&gt;Every scan run should log the active ceiling and its source.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fix ceiling: conservative
Source: repository configuration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The point is not to slow the agent down.&lt;/p&gt;

&lt;p&gt;To make authority visible, embed the active ceiling status directly into your PR templates. Don’t just show the &lt;em&gt;outcome&lt;/em&gt; of the agent’s work; show the &lt;em&gt;governance state&lt;/em&gt; that authorized it. A persistent ‘Governance Status’ block is the audit evidence your security team actually wants.&lt;/p&gt;

&lt;p&gt;This is the engine of CoCo Automations. As agents move from reactive tasks to proactive operations — like daily drift detection — the ‘conservative’ vs. ‘aggressive’ dial becomes our primary safety check. Setting these modes at the repository level ensures that even when the agent operates autonomously, it is tethered to a pre-approved ceiling of authority.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Visibility alone, however, is not a substitute for intervention.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Human override should always exist
&lt;/h3&gt;

&lt;p&gt;The needs-review route is not a dead end.&lt;/p&gt;

&lt;p&gt;It is the place where human judgment enters the workflow.&lt;/p&gt;

&lt;p&gt;A developer can review the issue, inspect the context, and decide whether the agent should proceed with the fix.&lt;/p&gt;

&lt;p&gt;Even for a complex issue.&lt;/p&gt;

&lt;p&gt;Even for a low-confidence issue.&lt;/p&gt;

&lt;p&gt;The override exists by design.&lt;/p&gt;

&lt;p&gt;Agent judgment is the default.&lt;/p&gt;

&lt;p&gt;Human judgment is the final decision.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;agent proposes &lt;strong&gt;-&amp;gt;&lt;/strong&gt; human decides &lt;strong&gt;-&amp;gt;&lt;/strong&gt; agent executes&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A system where the agent can never be overridden is broken.&lt;/p&gt;

&lt;p&gt;A system where the agent always acts is also broken.&lt;/p&gt;

&lt;p&gt;The override is the acknowledgement that developers know their codebases better than any model.&lt;/p&gt;

&lt;p&gt;They should always have the last word.&lt;/p&gt;

&lt;p&gt;This is where Agentic DevOps becomes useful.&lt;/p&gt;

&lt;p&gt;The agent is not replacing the engineer. It is doing the execution work after the engineer has set the boundary.&lt;/p&gt;

&lt;h3&gt;
  
  
  ICR did not drop. It got smarter.
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://blogs.kameshs.dev/intent-compression-ratio-measuring-the-power-of-intent-ceb6faf2e2f9" rel="noopener noreferrer"&gt;Intent Compression Ratio&lt;/a&gt; of this scaffold workflow is 48.&lt;/p&gt;

&lt;p&gt;One conversation instruction.&lt;/p&gt;

&lt;p&gt;48 distinct state-changing operations.&lt;/p&gt;

&lt;p&gt;That number did not change when I added the decision tree.&lt;/p&gt;

&lt;p&gt;What changed is that each operation now carries a risk assessment.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The agent that runs 48 operations conservatively is more useful than the agent that runs 48 operations blindly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The metric I track is not only ICR.&lt;/p&gt;

&lt;p&gt;I also track the agent-raised PR merge rate:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The percentage of agent-created PRs that engineers merge without modification.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That number measures trust.&lt;/p&gt;

&lt;p&gt;A team at 60%+ merge rate has accepted the agent as part of the workflow.&lt;/p&gt;

&lt;p&gt;A team at 10% has a noisy bot.&lt;/p&gt;

&lt;p&gt;Same ICR. Different values.&lt;/p&gt;

&lt;p&gt;Trust takes time.&lt;/p&gt;

&lt;p&gt;The conservative ceiling builds it.&lt;/p&gt;

&lt;h3&gt;
  
  
  What I mean by Agentic DevOps with CoCo
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Not&lt;/strong&gt; : replace engineers with AI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Yes&lt;/strong&gt; : give engineers a CI pipeline that knows its limits.&lt;/p&gt;

&lt;p&gt;The value is not faster code generation by itself.&lt;/p&gt;

&lt;p&gt;Faster generation without better control creates faster review queues and faster mistakes.&lt;/p&gt;

&lt;p&gt;The value is compressing the loop.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdmy00sc8glkp09310qxa.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdmy00sc8glkp09310qxa.png" alt="compressing the loop" width="302" height="800"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Where intent meets infrastructure: Integrating autonomous agents into traditional CI/CD loops.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That compression matters because the agent is calibrated.&lt;/p&gt;

&lt;p&gt;It does not open a PR for every needs-review issue.&lt;/p&gt;

&lt;p&gt;It does not silently change complex code because the prompt sounded confident.&lt;/p&gt;

&lt;p&gt;It does not confuse autonomy with permission.&lt;/p&gt;

&lt;p&gt;Agentic DevOps means the agent can say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I am not sure enough to act on this one.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is not a limitation.&lt;/p&gt;

&lt;p&gt;That is the design.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why this matters
&lt;/h3&gt;

&lt;p&gt;Most AI engineering conversations still treat autonomy as the finish line.&lt;/p&gt;

&lt;p&gt;Can the agent write the code?&lt;/p&gt;

&lt;p&gt;Can it open the PR?&lt;/p&gt;

&lt;p&gt;Can it deploy the change?&lt;/p&gt;

&lt;p&gt;Those are useful questions, but they are not the first questions.&lt;/p&gt;

&lt;p&gt;The first question should be:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What has to be true before the agent is allowed to act?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is where intent becomes operational.&lt;/p&gt;

&lt;p&gt;That is where policy becomes part of the development loop.&lt;/p&gt;

&lt;p&gt;That is where CoCo, CI, and IDD start to become more useful than a smarter autocomplete.&lt;/p&gt;

&lt;p&gt;Agentic DevOps is not about giving agents unlimited power.&lt;/p&gt;

&lt;p&gt;It is about giving them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;explicit intent&lt;/li&gt;
&lt;li&gt;bounded authority&lt;/li&gt;
&lt;li&gt;visible decisions&lt;/li&gt;
&lt;li&gt;human override&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the CI agent I want.&lt;/p&gt;

&lt;p&gt;One that knows how to act.&lt;/p&gt;

&lt;p&gt;And one that knows when not to.&lt;/p&gt;

&lt;p&gt;By making agentic authority visible and configurable, we are not just automating tasks; we are codifying intent. This is the final piece of the&lt;a href="https://blogs.kameshs.dev/intent-driven-development-the-shift-developers-cant-ignore-ef434f94d56c" rel="noopener noreferrer"&gt;Intent-Driven Development&lt;/a&gt; puzzle: ensuring that the ‘evidence’ generated by our agents maps directly back to human-authorized intent.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementation References
&lt;/h3&gt;

&lt;p&gt;The article describes the Agentic DevOps pattern rather than depending on a single repository. The following public references provide implementation context for the GitHub, GitLab, and Snowflake CoCo workflows discussed in this post.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CoCo skill&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/Snowflake-Labs/devops-snowflake-coco-agents" rel="noopener noreferrer"&gt;Snowflake-Labs/devops-snowflake-coco-agents&lt;/a&gt;&lt;br&gt;&lt;br&gt;
CoCo skill implementation for the DevOps agent workflow. This provides the core skill context behind scaffold, scan, issue routing, fix behavior, and the human-review loop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub template&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/Snowflake-Labs/github-coco-agent" rel="noopener noreferrer"&gt;Snowflake-Labs/github-coco-agent&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Template for exploring CoCo-driven Agentic DevOps workflows with GitHub Actions. It shows how the pattern maps to GitHub-native CI/CD, repository configuration, issue routing, and PR-based governance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitLab template&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/snowflake-dev/gitlab-coco-agent" rel="noopener noreferrer"&gt;snowflake-dev/gitlab-coco-agent&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Template for exploring the same Agentic DevOps workflow in GitLab CI. It shows that the pattern is not tied only to GitHub Actions and can be adapted across CI/CD systems.&lt;/p&gt;

&lt;h3&gt;
  
  
  Further Reading
&lt;/h3&gt;

&lt;p&gt;This post continues my Intent-Driven Development series:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blogs.kameshs.dev/infrastructure-as-intent-the-field-velocity-blueprint-e6217ef30f14" rel="noopener noreferrer"&gt;Infrastructure-as-Intent: The Field Velocity Blueprint&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blogs.kameshs.dev/the-ghost-in-the-machine-why-ai-needs-the-spirit-of-uml-0d8864e583e2" rel="noopener noreferrer"&gt;The Ghost in the Machine: Why AI Needs the Spirit of UML&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blogs.kameshs.dev/intent-driven-development-the-shift-developers-cant-ignore-ef434f94d56c" rel="noopener noreferrer"&gt;Intent-Driven Development: The Shift Developers Can’t Ignore&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blogs.kameshs.dev/intent-compression-ratio-measuring-the-power-of-intent-ceb6faf2e2f9" rel="noopener noreferrer"&gt;Intent Compression Ratio: Measuring the Power of Intent&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blogs.kameshs.dev/icr-and-token-economics-9a014a75b399" rel="noopener noreferrer"&gt;ICR and Token Economics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blogs.kameshs.dev/from-intent-to-evidence-why-ai-skills-need-tests-a48b3a43d971" rel="noopener noreferrer"&gt;From Intent to Evidence: Why AI Skills Need Tests&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For related thinking, Andrew Ng’s recent writing on &lt;a href="https://www.andrewng.org/writing/" rel="noopener noreferrer"&gt;Three Key Loops for Building Great Software&lt;/a&gt; and his &lt;a href="https://www.deeplearning.ai/courses/agentic-ai/" rel="noopener noreferrer"&gt;Agentic AI course&lt;/a&gt; reinforce the same direction: reliable AI systems are built around iterative loops, not one-shot prompts.&lt;/p&gt;

&lt;p&gt;That is the bridge this article explores.&lt;/p&gt;

&lt;p&gt;Intent gives the loop purpose.&lt;br&gt;&lt;br&gt;
Evidence gives the loop trust.&lt;br&gt;&lt;br&gt;
Policy gives the loop boundaries.&lt;br&gt;&lt;br&gt;
Human review gives the loop judgment.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclosure: Feature image generated with AI and reviewed by the author.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  About the Author
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Kamesh Sampath&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;is a Lead Developer Advocate at Snowflake, author, and long-time open-source contributor with 25+ years in enterprise software. He works across data engineering and AI with developer communities, helping practitioners turn modern data platforms into systems that hold up in production.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Through talks, writing, and hands-on demos, Kamesh makes cloud, data, and AI topics easier to understand and apply — grounded in real-world constraints. His sessions mix deep technical detail with practical patterns that developers and data teams can apply right away.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Lately, he’s been speaking about Apache NiFi (Snowflake Openflow), AI (Snowflake Cortex), and PostgreSQL.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;He believes technology becomes powerful when it is shared, taught, and built together.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kameshsampath" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; |&lt;a href="https://linkedin.com/in/kameshsampath" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; |&lt;a href="https://blogs.kameshs.dev/" rel="noopener noreferrer"&gt;Blog&lt;/a&gt; |&lt;a href="https://x.com/kamesh_sampath" rel="noopener noreferrer"&gt; X&lt;/a&gt;&lt;/p&gt;

</description>
      <category>snowflake</category>
      <category>cicd</category>
      <category>ai</category>
      <category>devops</category>
    </item>
    <item>
      <title>From Intent to Evidence: Why AI Skills Need Tests</title>
      <dc:creator>Kamesh Sampath</dc:creator>
      <pubDate>Mon, 22 Jun 2026 13:37:42 +0000</pubDate>
      <link>https://dev.to/kameshsampath/from-intent-to-evidence-why-ai-skills-need-tests-2j40</link>
      <guid>https://dev.to/kameshsampath/from-intent-to-evidence-why-ai-skills-need-tests-2j40</guid>
      <description>&lt;p&gt;&lt;em&gt;Moving beyond “it worked once” to build verifiable, trustworthy AI agents in real-world developer workflows.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8oxnpmfo100ygj051gm3.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8oxnpmfo100ygj051gm3.png" alt="From Intent to Evidence" width="800" height="534"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Intent is the source. Evidence is the contract.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;AI skills should not be trusted because they worked once. They should be trusted because they can reach the intended state repeatedly, with executable tests proving the outcome.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI&lt;/strong&gt; agents are easy to celebrate when they work once, but that is also the trap. The demo runs, the code looks right, the file appears in the right place, and everyone nods. Then you run it again. This time a file is missing, a parameter is read differently, or a command is skipped. The final result is close, but not correct. This is where AI-native development gets real: we do not only need agents that can generate; we need skills that can be trusted.&lt;/p&gt;

&lt;p&gt;In my earlier posts on Infrastructure-as-Intent, Intent-Driven Development, Intent Compression Ratio, and token economics, I argued that developers are moving away from writing every step by hand and toward expressing outcomes. Not every command, not every click, and not every line of glue code — just the outcome. But there is a missing layer in that story. Intent needs evidence.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Without evidence, intent is only a better prompt&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  “It Worked Once” Is Not Engineering
&lt;/h3&gt;

&lt;p&gt;Every developer knows this. We do not trust code because it compiled once, we do not trust infrastructure because one deployment succeeded, and we do not trust an API because one request returned 200 OK. We trust systems when we can verify them again and again.&lt;/p&gt;

&lt;p&gt;AI skills should be held to the same standard. Today, many AI workflows still feel like demo-driven development: we run an agent, inspect the output, and if it looks good, we move on. That is fine for exploration, but it is not enough for reusable skills.&lt;/p&gt;

&lt;p&gt;A reusable skill needs a stronger question. Not: &lt;em&gt;did the agent produce something useful?&lt;/em&gt; But rather: &lt;em&gt;did the system reach the intended state, and can it do that again?&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Gap Between Output and Outcome
&lt;/h3&gt;

&lt;p&gt;There is a gap between a plausible result and a proven result. I call this the &lt;strong&gt;Verification Gap&lt;/strong&gt;. On one hand, the agent gives an answer that looks right. On the other hand, the system is in the correct state. That gap matters because AI agents operate through probabilistic reasoning. The same instruction can lead to different paths, tools, or decisions depending on context and model behavior. Often those paths converge on the same outcome. Sometimes they do not.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffcz47mo2x4ithhury429.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffcz47mo2x4ithhury429.png" alt="The Verification Gap" width="799" height="160"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The Verification Gap: The difference between an agent generating a plausible output and proving the system actually reached the correct state.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The mistake is not using AI; the mistake is assuming one successful run is proof. A better question is: how do we make non-deterministic behavior measurable enough for developers to work with? An answer that looks right is not the same as a system that is right.&lt;/p&gt;

&lt;h3&gt;
  
  
  CoCo as the Proving Ground
&lt;/h3&gt;

&lt;p&gt;I encountered this problem firsthand while building skills for &lt;a href="https://docs.snowflake.com/en/user-guide/cortex-code/cortex-code" rel="noopener noreferrer"&gt;Snowflake Cortex Code&lt;/a&gt;, also known as CoCo. Because CoCo is an agentic coding assistant that combines reasoning, tool use, and code execution, it acts as a practical environment for testing AI skills in real-world workflows. I needed a way to prove that an agent’s answer wasn’t just plausible, but that the system was actually in the right state. That practical need led me to build inspect-coco.&lt;/p&gt;

&lt;p&gt;A CoCo skill can package developer intent into a reusable capability. Instead of asking an agent to reason from scratch every time, we can give it a skill that captures a workflow, convention, tool pattern, or common engineering task. This is the shift I described in Infrastructure-as-Intent: we move from prescribing steps to expressing outcomes, turning a skill into a reusable unit of intent.&lt;/p&gt;

&lt;p&gt;That is powerful, but it is also risky if we do not test it. A skill can hide many actions behind one instruction — it may create files, change configurations, call tools, or update a project. The user sees a simple request, and the skill performs the work. This is exactly what I mean by Intent Compression Ratio. A high-value skill compresses many steps into one intent, but high compression requires high confidence. If one intent represents ten steps, we need to know whether all ten steps completed correctly.&lt;/p&gt;

&lt;p&gt;The same challenge exists whether you are building skills for CoCo, Claude Code, Codex, Gemini CLI, OpenHands, or any other agentic development environment. Once an agent can inspect repositories, modify files, execute commands, and automate parts of the software lifecycle, the question becomes the same: how do we know it did the right thing?&lt;/p&gt;

&lt;p&gt;CoCo exposed the gap early. It became the first proving ground because it offered a practical environment where skills could interact with real projects, tools, and workflows. That made it easier to test a simple question: can intent be translated into repeatable, verifiable outcomes?&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8sbr9gvgkifdxzd333jz.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8sbr9gvgkifdxzd333jz.png" alt="inspect-coco" width="797" height="130"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;inspect-coco bridges the foundational evaluation capabilities of Inspect AI with the concrete execution environment of Snowflake CoCo.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;While the pattern is not limited to CoCo, CoCo is the concrete runtime. Inspect AI is the evaluation foundation. inspect-coco connects the two.&lt;/p&gt;

&lt;h3&gt;
  
  
  What inspect-coco Does ?
&lt;/h3&gt;

&lt;p&gt;inspect-coco is a developer-first test harness for the instructions and workflows that become AI skills. The flow is intentionally familiar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It uses &lt;strong&gt;Inspect AI&lt;/strong&gt; to run evaluations.&lt;/li&gt;
&lt;li&gt;It uses &lt;strong&gt;CoCo&lt;/strong&gt; to execute the skill.&lt;/li&gt;
&lt;li&gt;It uses &lt;strong&gt;Docker&lt;/strong&gt; to isolate the environment.&lt;/li&gt;
&lt;li&gt;It uses a &lt;strong&gt;test script&lt;/strong&gt; to verify the result.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftcreplghx2qsh8rk033i.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftcreplghx2qsh8rk033i.png" alt="The core evaluation loop" width="800" height="189"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The core evaluation loop: translating intent into execution, verification, and reliable measurement.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The key is the test. inspect-coco does not ask another model whether the answer looks good; it runs the skill and checks the system state. Did the file exist? Did the content match? Did the command succeed, and did the project end up in the expected shape?&lt;/p&gt;

&lt;p&gt;If yes, the test passes; if not, it fails. That is a language developers already understand. If you prefer, the verification layer can also use familiar testing frameworks such as pytest, allowing teams to reuse existing assertions, fixtures, and testing practices instead of learning a new evaluation model. The important idea is not the framework itself, but that the outcome is verified by executable tests rather than judged by appearance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Three Files
&lt;/h3&gt;

&lt;p&gt;An evaluation can start with just three files. That is intentional; no heavy platform is required to understand the idea.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;instruction.md (Markdown) describes the intent.&lt;/li&gt;
&lt;li&gt;tests/test.sh (Shell script) verifies the outcome.&lt;/li&gt;
&lt;li&gt;task.toml (TOML) tells the evaluation how to run.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7f4malyup7od42ktscz0.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7f4malyup7od42ktscz0.png" alt="A developer-first evaluation" width="800" height="476"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;A developer-first evaluation requires minimal overhead: intent, verification, and configuration.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The simplest example is the hello-world evaluation in the repository. The instruction asks the skill to create /workspace/hello.txt. The agent can choose its path, but the test objectively checks the result: does the file exist, and does the content match exactly? Exit 0 means pass; anything else means failure.&lt;/p&gt;

&lt;p&gt;That is boring in the best possible way.&lt;/p&gt;

&lt;h3&gt;
  
  
  Unit Tests for Skill Instructions
&lt;/h3&gt;

&lt;p&gt;One design choice in inspect-coco is worth calling out: it does not require starting with a fully packaged skill and running the whole lifecycle end to end. It can start with an instruction. That instruction may later become part of a CoCo skill, a Claude Code command, a Codex workflow, or another agentic environment. But before it becomes reusable automation, the instruction itself should be tested.&lt;/p&gt;

&lt;p&gt;A skill is not only code; it is packaged intent. If the intent is vague, the skill will be vague. If the instruction is hard to verify, the skill will be hard to trust. If the constraints are weak, the agent has too much room to improvise. Because of this, inspect-coco treats the instruction as a testable artifact, making it closer to unit testing for instructions than demo testing for agents.&lt;/p&gt;

&lt;p&gt;The question is not just whether the complete agent workflow can succeed. The earlier question is whether the instruction is clear, constrained, and verifiable enough to become a reliable skill in the first place. Instruction-level tests tell us if the unit of intent is well-formed before packaging it, while end-to-end tests tell us if the whole workflow actually worked. Both are useful, but they answer fundamentally different questions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Intent Needs Structure
&lt;/h3&gt;

&lt;p&gt;The instruction follows a simple structure, where each section has a specific job:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Goal:&lt;/strong&gt; Says what we want.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Requirements:&lt;/strong&gt; Say what must be true.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Constraints:&lt;/strong&gt; Reduce unwanted choices.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Output:&lt;/strong&gt; Tells us what success looks like.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This structure matters because vague intent creates drift. If the instruction is loose, the agent has more room to guess. It may still produce something useful, but useful is not the same as correct. A good instruction narrows the space. It does not remove all non-determinism, but it makes the outcome easier to test.&lt;/p&gt;

&lt;p&gt;To enforce this, inspect-coco also includes an IDD-style check for instruction quality, catching weak instructions early. The framework does not only ask if the skill worked; it also asks if the intent was clear enough to test.&lt;/p&gt;

&lt;h3&gt;
  
  
  Repeated Runs Matter
&lt;/h3&gt;

&lt;p&gt;One passing run is useful; it tells us the skill can work. But it does not tell us whether the skill is reliable. Because AI systems vary between runs, inspect-coco can execute the same task multiple times, measuring results across epochs and reporting pass rates such as pass@k.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3eyvvqj2ywsg1g76mxi3.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3eyvvqj2ywsg1g76mxi3.png" alt="Measuring reliability" width="800" height="854"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Measuring reliability: Because AI systems are non-deterministic, true confidence comes from repeated execution and measuring stability over time.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A skill that passes once out of three is not the same as a skill that passes ten out of ten. Both may look good in a demo, but only one is ready to trust. The goal is not to pretend AI is deterministic; rather, it is to measure how stable the outcome is. This is where evaluation becomes more than a checklist — it becomes a feedback loop.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Not Just Use LLM-as-Judge?
&lt;/h3&gt;

&lt;p&gt;LLM-as-judge has value when the output is subjective. A summary may need to be judged for clarity, a response checked for tone, or a support answer reviewed for usefulness.&lt;/p&gt;

&lt;p&gt;But many developer tasks are not subjective. A file exists or it does not. A test passes or it does not. A command exits cleanly or it does not. A generated project runs or it does not. For those cases, we should not ask for an opinion; we should run a test.&lt;/p&gt;

&lt;p&gt;That is the design choice behind inspect-coco: when the outcome can be verified by the system, the system should verify it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Inspect AI ?
&lt;/h3&gt;

&lt;p&gt;I built inspect-coco on &lt;a href="https://inspect.aisi.org.uk/" rel="noopener noreferrer"&gt;Inspect AI&lt;/a&gt; because agent evaluation needs more than prompt scoring. Developer skills often act in a real environment: they create files, modify projects, run commands, and use tools. So, the evaluation framework needs to support real execution.&lt;/p&gt;

&lt;p&gt;Inspect AI provides that foundation, giving us tasks, solvers, scorers, sandboxes, repeated runs, and logs. inspect-coco adds a CoCo-specific layer on top:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CoCo execution&lt;/li&gt;
&lt;li&gt;CoCo skill scaffolding&lt;/li&gt;
&lt;li&gt;IDD instruction checks&lt;/li&gt;
&lt;li&gt;Docker-based environments&lt;/li&gt;
&lt;li&gt;Snowflake authentication via OAuth, personal access tokens, and JWT&lt;/li&gt;
&lt;li&gt;Script-based verification&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the important split. Inspect AI is the general evaluation foundation, CoCo is the concrete runtime where I am proving the pattern, and inspect-coco connects the two for developers who want to build reliable CoCo skills today.&lt;/p&gt;

&lt;h3&gt;
  
  
  Developer-First by Design
&lt;/h3&gt;

&lt;p&gt;I wanted this to feel like normal development. Not like a research project, not like a dashboard-first platform, and not like another abstract AI evaluation layer. A developer should be able to look at the files and understand what is happening:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Markdown&lt;/strong&gt; for intent&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shell&lt;/strong&gt; for verification&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TOML&lt;/strong&gt; for configuration&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker&lt;/strong&gt; for isolation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CLI&lt;/strong&gt; for execution&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pass or fail&lt;/strong&gt; for confidence&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is the whole point. AI changes how we build, but it should not remove the habits that made software engineering work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Evaluation Should Be Close to the Skill
&lt;/h3&gt;

&lt;p&gt;inspect-coco can scaffold evaluations from an existing CoCo plugin, meaning a skill can grow a test right beside it. This is important because testing should not feel like a separate ceremony. If writing evaluations is too far away from writing skills, developers will skip it.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftcreplghx2qsh8rk033i.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftcreplghx2qsh8rk033i.png" alt="The local evaluation loop" width="800" height="189"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The local evaluation loop: Bringing testing closer to the skill development process prevents evaluation from becoming a skipped ceremony.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The closer the test is to the skill, the more likely it becomes part of the workflow. That is how software teams learned to treat tests, and AI skill development should learn the same lesson.&lt;/p&gt;

&lt;h3&gt;
  
  
  From Prompt Engineering to Intent Engineering
&lt;/h3&gt;

&lt;p&gt;Prompt engineering taught us how to talk to models. Intent engineering asks a harder question: can we express the outcome clearly enough for a system to act on it? But there is an even more important question after that: can we prove the system reached that outcome?&lt;/p&gt;

&lt;p&gt;This is where AI-native development has to mature. The future will not belong to teams that generate the most code; it will belong to teams that can express intent clearly, compress complexity safely, and verify outcomes continuously. CoCo skills give us a way to package intent, and inspect-coco gives us a way to test it. That is the bridge from intent to evidence.&lt;/p&gt;

&lt;p&gt;In Intent-Driven Development, the question is not only whether the agent produced something. The better question is whether the system reached the intended state, and whether it can do it again. That is what we should measure, and that is what we should improve. That is what turns AI skills from impressive demos into reliable developer tools.&lt;/p&gt;

&lt;p&gt;Intent is the source. Evidence is the contract. Every serious AI skill needs tests.&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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AK4inKdZnD_u_O67feIyaGg.gif" 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%2Fcdn-images-1.medium.com%2Fmax%2F1024%2F1%2AK4inKdZnD_u_O67feIyaGg.gif" alt="inspect-coco in action" width="760" height="380"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Demo GIF in the article showing inspect-coco in action.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  References and Further Reading
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Project&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/kameshsampath/inspect-coco/" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://kameshsampath.github.io/inspect-coco/" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/kameshsampath/inspect-coco/tree/main/examples/hello-world" rel="noopener noreferrer"&gt;hello-worldExample&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Snowflake and CoCo&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.google.com/search?q=https://docs.snowflake.com/en/user-guide/snowflake-cortex/cortex-code" rel="noopener noreferrer"&gt;Snowflake Cortex Code documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.snowflake.com/en/developers/guides/sfguide-build-end-to-end-ai-app-on-snowflake/" rel="noopener noreferrer"&gt;Snowflake CoCo Quickstart&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;My IDD Series&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://blogs.kameshs.dev/infrastructure-as-intent-the-field-velocity-blueprint-e6217ef30f14" rel="noopener noreferrer"&gt;Infrastructure-as-Intent: The Field Velocity Blueprint&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blogs.kameshs.dev/the-ghost-in-the-machine-why-ai-needs-the-spirit-of-uml-0d8864e583e2" rel="noopener noreferrer"&gt;The Ghost in the Machine: Why AI Needs the Spirit of UML&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blogs.kameshs.dev/intent-driven-development-the-shift-developers-cant-ignore-ef434f94d56c" rel="noopener noreferrer"&gt;Intent-Driven Development: The Shift Developers Can’t Ignore&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blogs.kameshs.dev/intent-compression-ratio-measuring-the-power-of-intent-ceb6faf2e2f9" rel="noopener noreferrer"&gt;Intent Compression Ratio: Measuring the Power of Intent&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blogs.kameshs.dev/icr-and-token-economics-9a014a75b399" rel="noopener noreferrer"&gt;ICR and Token Economics&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Related Reading&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://inspect.ai-safety-institute.org.uk/" rel="noopener noreferrer"&gt;Inspect AI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/openai/evals" rel="noopener noreferrer"&gt;OpenAI Evals&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.promptfoo.dev/" rel="noopener noreferrer"&gt;Promptfoo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/confident-ai/deepeval" rel="noopener noreferrer"&gt;DeepEval&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.swebench.com/" rel="noopener noreferrer"&gt;SWE-bench&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  About the Author
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Kamesh Sampath&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;is a Lead Developer Advocate at Snowflake, author, and long-time open-source contributor with 25+ years in enterprise software. He works across data engineering and AI with developer communities, helping practitioners turn modern data platforms into systems that hold up in production.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Through talks, writing, and hands-on demos, Kamesh makes cloud, data, and AI topics easier to understand and apply — grounded in real-world constraints. His sessions mix deep technical detail with practical patterns that developers and data teams can apply right away.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Lately, he’s been speaking about Apache NiFi (Snowflake Openflow), AI (Snowflake Cortex), and PostgreSQL.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;He believes technology becomes powerful when it is shared, taught, and built together.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kameshsampath" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; |&lt;a href="https://linkedin.com/in/kameshsampath" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; |&lt;a href="https://blogs.kameshs.dev/" rel="noopener noreferrer"&gt;Blog&lt;/a&gt; |&lt;a href="https://x.com/kamesh_sampath" rel="noopener noreferrer"&gt; X&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>devtools</category>
      <category>softwaretesting</category>
      <category>agents</category>
    </item>
    <item>
      <title>ICR and Token Economics</title>
      <dc:creator>Kamesh Sampath</dc:creator>
      <pubDate>Wed, 20 May 2026 03:26:00 +0000</pubDate>
      <link>https://dev.to/kameshsampath/icr-and-token-economics-516b</link>
      <guid>https://dev.to/kameshsampath/icr-and-token-economics-516b</guid>
      <description>&lt;p&gt;&lt;em&gt;Why the hidden cost of low-intent AI systems is not just more tokens, but weaker architecture.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm8vivmntzngj0az9jn5f.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fm8vivmntzngj0az9jn5f.png" alt="ICR and Token Economics" width="800" height="534"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;From prompt optimization to intent optimization: higher ICR means more useful work, fewer wasted tokens, and better token economics.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;We talk a lot about tokens.&lt;/p&gt;

&lt;p&gt;Input tokens.&lt;br&gt;&lt;br&gt;
Output tokens.&lt;br&gt;&lt;br&gt;
Context windows.&lt;br&gt;&lt;br&gt;
Pricing.&lt;br&gt;&lt;br&gt;
Latency.&lt;br&gt;&lt;br&gt;
Caching.&lt;/p&gt;

&lt;p&gt;But I think we are missing the deeper question.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why are we using so many tokens in the first place?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Most conversations about token optimization start too late. They focus on trimming prompts, compressing context, caching responses, or choosing cheaper models.&lt;/p&gt;

&lt;p&gt;Those things matter.&lt;/p&gt;

&lt;p&gt;But they are symptoms.&lt;/p&gt;

&lt;p&gt;The deeper issue is often not the model.&lt;/p&gt;

&lt;p&gt;It is the interaction architecture.&lt;/p&gt;

&lt;p&gt;A weak interaction architecture forces the user to explain too much, repeat too much, clarify too much, and carry too much system knowledge in every request.&lt;/p&gt;

&lt;p&gt;That is not just a usability problem.&lt;/p&gt;

&lt;p&gt;It is an economic problem.&lt;/p&gt;

&lt;p&gt;Because in AI-native systems, tokens are no longer just text.&lt;/p&gt;

&lt;p&gt;Tokens are infrastructure.&lt;/p&gt;

&lt;p&gt;They affect cost.&lt;br&gt;&lt;br&gt;
They affect latency.&lt;br&gt;&lt;br&gt;
They affect context capacity.&lt;br&gt;&lt;br&gt;
They affect reliability.&lt;br&gt;&lt;br&gt;
They affect how much useful work an AI system can perform before the interaction collapses under its own verbosity.&lt;/p&gt;

&lt;p&gt;This is where Intent Compression Ratio (ICR) becomes useful.&lt;/p&gt;

&lt;p&gt;In my previous article, &lt;a href="https://blogs.kameshs.dev/intent-compression-ratio-measuring-the-power-of-intent-ceb6faf2e2f9" rel="noopener noreferrer"&gt;Intent Compression Ratio: Measuring the Power of Intent&lt;/a&gt;, I looked at ICR as a way to understand how much procedural complexity moves from the developer to the system.&lt;/p&gt;

&lt;p&gt;In this post, I want to look at the same idea from another angle:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What happens to token economics when intent is poorly compressed?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  The Token Problem Is Not Just Token Count
&lt;/h3&gt;

&lt;p&gt;It is tempting to think token optimization means making prompts shorter.&lt;/p&gt;

&lt;p&gt;That is only partially true.&lt;/p&gt;

&lt;p&gt;A short prompt can be bad if it is ambiguous.&lt;/p&gt;

&lt;p&gt;A long prompt can be necessary if the system has no context.&lt;/p&gt;

&lt;p&gt;The real question is simpler:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How many tokens does the system need to faithfully understand and fulfill the user’s intent?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is the &lt;strong&gt;economic unit&lt;/strong&gt; that matters.&lt;/p&gt;

&lt;p&gt;Not prompt length alone.&lt;/p&gt;

&lt;p&gt;Not output length alone.&lt;/p&gt;

&lt;p&gt;But the total token footprint required to move from intent to outcome.&lt;/p&gt;

&lt;p&gt;That includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first prompt.&lt;/li&gt;
&lt;li&gt;The clarification turns.&lt;/li&gt;
&lt;li&gt;The repeated context.&lt;/li&gt;
&lt;li&gt;The hidden system instructions.&lt;/li&gt;
&lt;li&gt;The tool call explanations.&lt;/li&gt;
&lt;li&gt;The retries.&lt;/li&gt;
&lt;li&gt;The corrections.&lt;/li&gt;
&lt;li&gt;The familiar “no, that is not what I meant” loop.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you add all of that up, a small human request can become a very large machine interaction.&lt;/p&gt;

&lt;p&gt;I call this &lt;strong&gt;token amplification&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Token Amplification
&lt;/h3&gt;

&lt;p&gt;Token amplification happens when compact human intent expands into a disproportionately large token footprint.&lt;/p&gt;

&lt;p&gt;For example, a developer may say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Deploy the payment service with autoscaling and observability.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is a compact intent.&lt;/p&gt;

&lt;p&gt;But in a low-ICR system, the developer may need to explain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What service means.&lt;/li&gt;
&lt;li&gt;Which environment.&lt;/li&gt;
&lt;li&gt;Which runtime.&lt;/li&gt;
&lt;li&gt;Which scaling rules.&lt;/li&gt;
&lt;li&gt;Which observability stack.&lt;/li&gt;
&lt;li&gt;Which naming conventions.&lt;/li&gt;
&lt;li&gt;Which security constraints.&lt;/li&gt;
&lt;li&gt;Which deployment policy.&lt;/li&gt;
&lt;li&gt;Which rollback behavior.&lt;/li&gt;
&lt;li&gt;Which team standards.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then the system asks clarifying questions.&lt;/p&gt;

&lt;p&gt;Then the user repeats context.&lt;/p&gt;

&lt;p&gt;Then the system generates something close, but not quite right.&lt;/p&gt;

&lt;p&gt;Then the user corrects it.&lt;/p&gt;

&lt;p&gt;By the end, the original intent has become a long token trail.&lt;/p&gt;

&lt;p&gt;The system did not use more tokens because it understood more.&lt;/p&gt;

&lt;p&gt;It used more tokens because it understood less.&lt;/p&gt;

&lt;p&gt;That distinction matters.&lt;/p&gt;

&lt;h3&gt;
  
  
  ICR as an Economic Signal
&lt;/h3&gt;

&lt;p&gt;For this discussion, I use a deliberately simple version of ICR:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;ICR = Intent Fulfilled / Total Tokens&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Higher ICR means more useful work completed per token consumed.&lt;/p&gt;

&lt;p&gt;Lower ICR means the system burns more tokens to achieve the same outcome.&lt;/p&gt;

&lt;p&gt;This makes ICR more than a developer experience idea.&lt;/p&gt;

&lt;p&gt;It is also a cost metric.&lt;/p&gt;

&lt;p&gt;A high-ICR system does not merely feel better to use.&lt;/p&gt;

&lt;p&gt;It is more economical.&lt;/p&gt;

&lt;p&gt;It reduces repeated explanations.&lt;br&gt;&lt;br&gt;
It reduces clarification loops.&lt;br&gt;&lt;br&gt;
It reduces redundant context transfer.&lt;br&gt;&lt;br&gt;
It reduces orchestration overhead.&lt;br&gt;&lt;br&gt;
It reduces the probability of retries.&lt;/p&gt;

&lt;p&gt;That means token optimization is not only a prompt engineering problem.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It is an intent design problem.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Prompt Verbosity Is Often a Tax on Missing Intent
&lt;/h3&gt;

&lt;p&gt;We have all seen this pattern.&lt;/p&gt;

&lt;p&gt;A prompt starts simple.&lt;/p&gt;

&lt;p&gt;Then it grows.&lt;/p&gt;

&lt;p&gt;“Act as a senior engineer…”&lt;/p&gt;

&lt;p&gt;“Follow these conventions…”&lt;/p&gt;

&lt;p&gt;“Use this format…”&lt;/p&gt;

&lt;p&gt;“Do not forget…”&lt;/p&gt;

&lt;p&gt;“Before answering…”&lt;/p&gt;

&lt;p&gt;“Assume the following context…”&lt;/p&gt;

&lt;p&gt;“Here are the constraints…”&lt;/p&gt;

&lt;p&gt;“Here are examples…”&lt;/p&gt;

&lt;p&gt;“Here are exceptions to the examples…”&lt;/p&gt;

&lt;p&gt;Some of this is useful.&lt;/p&gt;

&lt;p&gt;But often, prompt verbosity is compensating for missing system memory, missing context, missing abstractions, or missing intent contracts.&lt;/p&gt;

&lt;p&gt;The user is not just expressing the goal.&lt;/p&gt;

&lt;p&gt;The user is rebuilding the world around the goal.&lt;/p&gt;

&lt;p&gt;Every time.&lt;/p&gt;

&lt;p&gt;That is expensive.&lt;/p&gt;

&lt;p&gt;Not only in dollars, but in cognition.&lt;/p&gt;

&lt;p&gt;The developer becomes responsible for carrying the system model in their head and serializing it into text repeatedly.&lt;/p&gt;

&lt;p&gt;That is not intelligence.&lt;/p&gt;

&lt;p&gt;That is manual context transport.&lt;/p&gt;

&lt;h3&gt;
  
  
  Skills Are Where Intent Becomes Executable
&lt;/h3&gt;

&lt;p&gt;Intent by itself is not enough.&lt;/p&gt;

&lt;p&gt;If I say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Deploy the payment service.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The system still needs to know what “deploy” means in my environment.&lt;/p&gt;

&lt;p&gt;Does it mean Kubernetes? &lt;a href="https://docs.snowflake.com/en/developer-guide/snowpark-container-services/overview" rel="noopener noreferrer"&gt;Snowpark Container Services&lt;/a&gt;? Terraform? A CI/CD pipeline? A staging rollout first? Which observability defaults? Which governance rules? Which rollback policy?&lt;/p&gt;

&lt;p&gt;This is why skills are becoming such an important primitive in agentic systems.&lt;/p&gt;

&lt;p&gt;Claude has Skills. Cortex Code has Skills. Gemini has Gems. Codex has Skills.&lt;/p&gt;

&lt;p&gt;Different names, but they point in a similar direction.&lt;/p&gt;

&lt;p&gt;A skill is not just a saved prompt.&lt;/p&gt;

&lt;p&gt;At its best, a skill is compressed operational knowledge.&lt;/p&gt;

&lt;p&gt;It can encode the steps, constraints, conventions, tools, expected output, safety boundaries, and domain-specific judgment required to complete a recurring task.&lt;/p&gt;

&lt;p&gt;Without skills, the user has to serialize all of that context into the prompt.&lt;/p&gt;

&lt;p&gt;With skills, the system can load the right operational pattern and execute the intent with less repeated explanation.&lt;/p&gt;

&lt;p&gt;That is ICR in practice.&lt;/p&gt;

&lt;p&gt;The human expression gets smaller, but the executable meaning gets richer.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Economics of Repetition
&lt;/h3&gt;

&lt;p&gt;The point is not to make every prompt shorter.&lt;/p&gt;

&lt;p&gt;The point is to stop repeating what the system should already know.&lt;/p&gt;

&lt;p&gt;A lot of token waste does not come from the user’s intent.&lt;/p&gt;

&lt;p&gt;It comes from everything wrapped around the intent.&lt;/p&gt;

&lt;p&gt;The same architectural context.&lt;br&gt;&lt;br&gt;
The same coding standards.&lt;br&gt;&lt;br&gt;
The same deployment rules.&lt;br&gt;&lt;br&gt;
The same governance constraints.&lt;br&gt;&lt;br&gt;
The same output format.&lt;br&gt;&lt;br&gt;
The same safety instructions.&lt;/p&gt;

&lt;p&gt;Again and again.&lt;/p&gt;

&lt;p&gt;In a single prompt, this feels harmless.&lt;/p&gt;

&lt;p&gt;Across a workflow, it becomes expensive.&lt;/p&gt;

&lt;p&gt;Across agents, tools, and retries, it becomes amplification.&lt;/p&gt;

&lt;p&gt;This is the economics of repetition.&lt;/p&gt;

&lt;p&gt;Low-ICR systems make humans restate context.&lt;/p&gt;

&lt;p&gt;High-ICR systems turn repeated context into reusable capability.&lt;/p&gt;

&lt;p&gt;That is why skills matter.&lt;/p&gt;

&lt;p&gt;A skill is one way to stop paying the repetition tax every time. It packages recurring operational knowledge so the user can express the outcome instead of re-explaining the procedure.&lt;/p&gt;

&lt;p&gt;The token savings are not just from fewer words.&lt;/p&gt;

&lt;p&gt;They come from moving repeated meaning out of the prompt path and into the system.&lt;/p&gt;

&lt;p&gt;But compression creates a second responsibility: transparency.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Small Experiment: ICR Lab
&lt;/h3&gt;

&lt;p&gt;To make this visible, I built a small open-source &lt;a href="https://streamlit.io" rel="noopener noreferrer"&gt;Streamlit&lt;/a&gt; app called &lt;a href="https://github.com/kameshsampath/icr-lab" rel="noopener noreferrer"&gt;ICR Lab&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The app is intentionally simple. It does not call a live LLM, benchmark models, or try to be an agent framework.&lt;/p&gt;

&lt;p&gt;It simulates token behavior across different interaction styles so the economics are easier to see.&lt;/p&gt;

&lt;p&gt;The current version compares five modes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Verbose Prompting&lt;/strong&gt; : large prompts with repeated context.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clarification Heavy&lt;/strong&gt; : multiple rounds of back-and-forth before the system can act.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Context-Aware&lt;/strong&gt; : the system reuses some context and reduces repeated explanation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Intent-Optimized&lt;/strong&gt; : the user expresses compact semantic intent and the system assumes more structured responsibility.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Over-Compressed&lt;/strong&gt; : the user strips so much context that the system misinterprets the intent, triggering correction rounds that amplify tokens beyond what a verbose prompt would have cost.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The line I keep coming back to is this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Same intent. Different interaction architecture. Different token economics.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqmyff7clm4k5v8gmx5cs.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqmyff7clm4k5v8gmx5cs.png" alt="Token Economics" width="800" height="604"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Same intent. Different interaction architecture. Different token economics. ICR Lab visualizes how token amplification changes across interaction modes.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;That is the entire point of the demo.&lt;/p&gt;

&lt;p&gt;The task does not change.&lt;/p&gt;

&lt;p&gt;The model does not change.&lt;/p&gt;

&lt;p&gt;The interaction pattern changes.&lt;/p&gt;

&lt;p&gt;And the token footprint changes with it.&lt;/p&gt;

&lt;p&gt;The fifth mode exists to prevent the wrong takeaway. Over-compression is not optimization. When the system lacks enough shared context to decompress a terse intent, it guesses wrong — and the correction cost exceeds the savings.&lt;/p&gt;

&lt;p&gt;ICR is not “make prompts shorter”. It is “make meaning denser”.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Wrong Lesson: Just Make Prompts Shorter
&lt;/h3&gt;

&lt;p&gt;There is a dangerous interpretation here.&lt;/p&gt;

&lt;p&gt;Someone might say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;So high ICR means shorter prompts?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Not exactly.&lt;/p&gt;

&lt;p&gt;A short prompt with no shared context is just ambiguity.&lt;/p&gt;

&lt;p&gt;A high-ICR interaction is not merely brief.&lt;/p&gt;

&lt;p&gt;It is dense.&lt;/p&gt;

&lt;p&gt;It carries more meaning per token because the surrounding system understands the domain, constraints, policies, tools, and desired state.&lt;/p&gt;

&lt;p&gt;That understanding can come from many places:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Platform profiles.&lt;/li&gt;
&lt;li&gt;Reusable skills.&lt;/li&gt;
&lt;li&gt;Semantic memory.&lt;/li&gt;
&lt;li&gt;Declarative manifests.&lt;/li&gt;
&lt;li&gt;Typed tool interfaces.&lt;/li&gt;
&lt;li&gt;Repository context.&lt;/li&gt;
&lt;li&gt;Organizational conventions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The point is not to delete words.&lt;/p&gt;

&lt;p&gt;The point is to stop repeating what the system should already know.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compression Without Visibility Is Opacity
&lt;/h3&gt;

&lt;p&gt;There is another trap.&lt;/p&gt;

&lt;p&gt;High compression can become dangerous when it hides too much.&lt;/p&gt;

&lt;p&gt;If I say:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Deploy the connector.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And the system creates users, roles, policies, network rules, secrets, and tasks behind the scenes, I may get a great experience.&lt;/p&gt;

&lt;p&gt;Until something breaks.&lt;/p&gt;

&lt;p&gt;Then I need to know what was created, in what order, with what constraints, which step failed, what can be retried safely, and what state was left behind.&lt;/p&gt;

&lt;p&gt;This is why ICR must be paired with transparency.&lt;/p&gt;

&lt;p&gt;The system should absorb complexity, but not erase visibility.&lt;/p&gt;

&lt;p&gt;High ICR without transparency is magic.&lt;/p&gt;

&lt;p&gt;High ICR with transparency is engineering.&lt;/p&gt;

&lt;p&gt;That distinction matters even more when money enters the picture.&lt;/p&gt;

&lt;p&gt;Token-efficient systems that are impossible to debug only move the cost elsewhere.&lt;/p&gt;

&lt;p&gt;They save tokens on the happy path and burn engineering hours during failure.&lt;/p&gt;

&lt;h3&gt;
  
  
  From Prompt Optimization to Intent Optimization
&lt;/h3&gt;

&lt;p&gt;Prompt optimization asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How do I phrase this better?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Intent optimization asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why does the user need to phrase this much at all?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is the deeper shift.&lt;/p&gt;

&lt;p&gt;The future of AI systems will not be defined only by larger context windows.&lt;/p&gt;

&lt;p&gt;Larger context windows help, but they can also hide bad architecture.&lt;/p&gt;

&lt;p&gt;If the system can accept more context, we may simply dump more context into it: more documents, more history, more instructions, more examples, more logs, more everything.&lt;/p&gt;

&lt;p&gt;But stuffing the context window is not the same as understanding intent.&lt;/p&gt;

&lt;p&gt;A bigger backpack does not make you organized.&lt;/p&gt;

&lt;p&gt;It just lets you carry more mess.&lt;/p&gt;

&lt;p&gt;The better direction is often not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Give the model more tokens.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Require fewer tokens to preserve the same intent.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is &lt;strong&gt;intent optimization&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What ICR Starts to Reveal
&lt;/h3&gt;

&lt;p&gt;Once you look at AI systems through ICR, a few things become obvious.&lt;/p&gt;

&lt;p&gt;A verbose prompt is not always rich intent.&lt;/p&gt;

&lt;p&gt;Sometimes it is a workaround for missing abstraction.&lt;/p&gt;

&lt;p&gt;A clarification loop is not always intelligence.&lt;/p&gt;

&lt;p&gt;Sometimes it is the system externalizing its uncertainty back onto the user.&lt;/p&gt;

&lt;p&gt;A large context window is not always better architecture.&lt;/p&gt;

&lt;p&gt;Sometimes it is a bigger place to store repeated noise.&lt;/p&gt;

&lt;p&gt;An agent workflow is not automatically efficient.&lt;/p&gt;

&lt;p&gt;Sometimes agents multiply token usage by passing bloated context between themselves.&lt;/p&gt;

&lt;p&gt;And a skill is not just automation.&lt;/p&gt;

&lt;p&gt;It is a compressed unit of repeatable intent.&lt;/p&gt;

&lt;p&gt;That last point matters.&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://blogs.kameshs.dev/intent-driven-development-the-shift-developers-cant-ignore-ef434f94d56c" rel="noopener noreferrer"&gt;Intent Driven Development&lt;/a&gt;, I argued that developers are not becoming less important because AI can generate code.&lt;/p&gt;

&lt;p&gt;They are becoming more important because the bottleneck has moved.&lt;/p&gt;

&lt;p&gt;The bottleneck is no longer syntax.&lt;/p&gt;

&lt;p&gt;It is clarity of intent.&lt;/p&gt;

&lt;p&gt;Token economics reinforces that shift.&lt;/p&gt;

&lt;p&gt;A vague developer with AI creates token sprawl.&lt;/p&gt;

&lt;p&gt;A precise developer with intent-aware systems creates leverage.&lt;/p&gt;

&lt;p&gt;After seeing these patterns, the next question is natural:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why simulate this instead of using a live LLM?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Why ICR Lab Uses Simulation
&lt;/h3&gt;

&lt;p&gt;ICR Lab v1 uses deterministic simulation instead of live model calls.&lt;/p&gt;

&lt;p&gt;That is deliberate.&lt;/p&gt;

&lt;p&gt;The goal is not to benchmark OpenAI, Anthropic, Snowflake Cortex, local models, or anything else.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The goal is to isolate the interaction pattern.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If the app used live LLM calls immediately, the conversation would drift into model quality.&lt;/p&gt;

&lt;p&gt;Which model is cheaper?&lt;br&gt;&lt;br&gt;
Which model answers better?&lt;br&gt;&lt;br&gt;
Which model counts tokens differently?&lt;br&gt;&lt;br&gt;
Which model follows instructions more reliably?&lt;/p&gt;

&lt;p&gt;Those are valid questions.&lt;/p&gt;

&lt;p&gt;But they are not the question I wanted to explore.&lt;/p&gt;

&lt;p&gt;The question is simpler:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How does interaction architecture change token economics?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Simulation keeps that visible.&lt;/p&gt;

&lt;p&gt;Same input.&lt;br&gt;&lt;br&gt;
Same modes.&lt;br&gt;&lt;br&gt;
Same curves.&lt;br&gt;&lt;br&gt;
Same comparison.&lt;/p&gt;

&lt;p&gt;No API keys.&lt;br&gt;&lt;br&gt;
No model variance.&lt;br&gt;&lt;br&gt;
No hidden backend.&lt;/p&gt;

&lt;p&gt;Live model integrations can come later.&lt;/p&gt;

&lt;p&gt;The concept needs to be clear before the instrumentation becomes real.&lt;/p&gt;

&lt;h3&gt;
  
  
  Closing Thought
&lt;/h3&gt;

&lt;p&gt;The future may not belong to systems that consume the most tokens.&lt;/p&gt;

&lt;p&gt;It may belong to systems that need the fewest tokens to understand us correctly.&lt;/p&gt;

&lt;p&gt;That does not mean smaller models.&lt;/p&gt;

&lt;p&gt;It does not mean shorter prompts.&lt;/p&gt;

&lt;p&gt;It does not mean hiding complexity behind magical interfaces.&lt;/p&gt;

&lt;p&gt;It means better intent architecture.&lt;/p&gt;

&lt;p&gt;Systems that know the context.&lt;br&gt;&lt;br&gt;
Systems that preserve constraints.&lt;br&gt;&lt;br&gt;
Systems that compress repeated patterns.&lt;br&gt;&lt;br&gt;
Systems that expose what they did.&lt;br&gt;&lt;br&gt;
Systems that turn verbose human instruction into transparent machine execution.&lt;/p&gt;

&lt;p&gt;That is where ICR and token economics meet.&lt;/p&gt;

&lt;p&gt;Not in counting tokens for the sake of counting tokens.&lt;/p&gt;

&lt;p&gt;But in asking a better question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How much useful intent did this system fulfill per token consumed?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That question changes the optimization target.&lt;/p&gt;

&lt;p&gt;And once you see it, token cost stops looking like a pricing problem alone.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It starts looking like a design problem.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Try the Demo
&lt;/h3&gt;

&lt;p&gt;I built a small companion app for this post: &lt;a href="https://icr-lab.streamlit.app/" rel="noopener noreferrer"&gt;ICR Lab&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It is open source and runs as a Streamlit app.&lt;/p&gt;

&lt;p&gt;The goal is simple:&lt;/p&gt;

&lt;p&gt;Enter a task.&lt;br&gt;&lt;br&gt;
Compare interaction modes.&lt;br&gt;&lt;br&gt;
Watch token amplification happen.&lt;br&gt;&lt;br&gt;
Then watch it collapse as intent gets better compressed.&lt;/p&gt;

&lt;p&gt;It is not a benchmark.&lt;/p&gt;

&lt;p&gt;It is a playground for building intuition.&lt;/p&gt;

&lt;p&gt;Because sometimes the best way to understand a systems problem is to make the invisible curve visible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Related Reading
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/kameshsampath/icr-lab" rel="noopener noreferrer"&gt;ICR Lab GitHub Repo&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://icr-lab.streamlit.app/" rel="noopener noreferrer"&gt;ICR Lab Live App&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blogs.kameshs.dev/infrastructure-as-intent-the-field-velocity-blueprint-e6217ef30f14" rel="noopener noreferrer"&gt;Infrastructure as Intent: The Field Velocity Blueprint&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blogs.kameshs.dev/the-ghost-in-the-machine-why-ai-needs-the-spirit-of-uml-0d8864e583e2" rel="noopener noreferrer"&gt;The Ghost in the Machine: Why AI Needs the Spirit of UML&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blogs.kameshs.dev/intent-driven-development-the-shift-developers-cant-ignore-ef434f94d56c" rel="noopener noreferrer"&gt;Intent Driven Development: The Shift Developers Can’t Ignore&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blogs.kameshs.dev/intent-compression-ratio-measuring-the-power-of-intent-ceb6faf2e2f9" rel="noopener noreferrer"&gt;Intent Compression Ratio: Measuring the Power of Intent&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  About the Author
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Kamesh Sampath&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;is a Lead Developer Advocate at Snowflake, author, and long-time open-source contributor with 25+ years in enterprise software. He works across data engineering and AI with developer communities, helping practitioners turn modern data platforms into systems that hold up in production.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Through talks, writing, and hands-on demos, Kamesh makes cloud, data, and AI topics easier to understand and apply — grounded in real-world constraints. His sessions mix deep technical detail with practical patterns that developers and data teams can apply right away.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Lately, he’s been speaking about Apache NiFi (Snowflake Openflow), AI (Snowflake Cortex), and PostgreSQL.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;He believes technology becomes powerful when it is shared, taught, and built together.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kameshsampath" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; |&lt;a href="https://linkedin.com/in/kameshsampath" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; |&lt;a href="https://blogs.kameshs.dev/" rel="noopener noreferrer"&gt;Blog&lt;/a&gt; |&lt;a href="https://x.com/kamesh_sampath" rel="noopener noreferrer"&gt; X&lt;/a&gt;&lt;/p&gt;

</description>
      <category>llm</category>
      <category>devrel</category>
      <category>platformengineering</category>
      <category>ai</category>
    </item>
    <item>
      <title>Intent Compression Ratio: Measuring the Power of Intent</title>
      <dc:creator>Kamesh Sampath</dc:creator>
      <pubDate>Mon, 11 May 2026 15:40:46 +0000</pubDate>
      <link>https://dev.to/kameshsampath/intent-compression-ratio-measuring-the-power-of-intent-2k97</link>
      <guid>https://dev.to/kameshsampath/intent-compression-ratio-measuring-the-power-of-intent-2k97</guid>
      <description>&lt;p&gt;&lt;em&gt;A way to measure how much procedural complexity moves from developers to AI agents, skills, and intent-driven systems.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwjewckycn4kdj4wm4tlg.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwjewckycn4kdj4wm4tlg.png" alt="ICR" width="800" height="534"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;From many operations to one intent: visualizing Intent Compression Ratio.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We’ve spent years optimizing execution.&lt;/p&gt;

&lt;p&gt;Better APIs.&lt;br&gt;&lt;br&gt;
Better CLIs.&lt;br&gt;&lt;br&gt;
Better automation.&lt;/p&gt;

&lt;p&gt;But developers don’t struggle because execution is slow.&lt;/p&gt;

&lt;p&gt;They struggle because execution is hidden.&lt;/p&gt;

&lt;p&gt;Infrastructure doesn’t fail loudly.&lt;br&gt;&lt;br&gt;
It fails silently — when you get the order or the desired state wrong.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Problem Isn’t Steps. It’s the Graph
&lt;/h3&gt;

&lt;p&gt;Take a realistic ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“I need to deploy a connector with Snowflake&lt;/em&gt; &lt;a href="https://docs.snowflake.com/en/user-guide/data-integration/openflow/about" rel="noopener noreferrer"&gt;&lt;em&gt;Openflow&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In practice, this often ends with generating a &lt;strong&gt;Programmatic Access Token (PAT)&lt;/strong&gt; to be used by clients like &lt;a href="https://nipyapi.readthedocs.io/en/latest/" rel="noopener noreferrer"&gt;&lt;strong&gt;Apache NiPyAPI&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But getting there is not one step.&lt;/p&gt;

&lt;p&gt;It’s a graph.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frk66niwhotf0lf5v96mx.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frk66niwhotf0lf5v96mx.png" alt="Intent Graph" width="798" height="216"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Programmatic Access Token flow as an execution graph: multiple object operations compressed into one intent.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Each node is valid on its own.&lt;/p&gt;

&lt;p&gt;But the ordering and desired state are not optional.&lt;/p&gt;

&lt;p&gt;A network policy must exist before it’s attached.&lt;br&gt;&lt;br&gt;
An auth policy must reference the correct role.&lt;br&gt;&lt;br&gt;
The PAT must be generated after all constraints are satisfied.&lt;/p&gt;

&lt;p&gt;Get this wrong?&lt;/p&gt;

&lt;p&gt;No exception.&lt;br&gt;&lt;br&gt;
No obvious failure.&lt;/p&gt;

&lt;p&gt;Just a token that doesn’t authenticate.&lt;br&gt;&lt;br&gt;
A connector that doesn’t connect.&lt;br&gt;&lt;br&gt;
And hours spent debugging across identity, network, and auth layers.&lt;/p&gt;

&lt;p&gt;Infrastructure is &lt;strong&gt;not procedural&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It is &lt;strong&gt;relational&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And we’ve been asking developers to execute that relationship manually.&lt;/p&gt;

&lt;p&gt;This is also why many AI agent workflows struggle today. We ask agents to operate on systems that still expose too much procedural complexity.&lt;/p&gt;

&lt;p&gt;If an agent has to reason through 12 procedural steps to achieve one outcome, the probability of a hallucinated configuration, missed dependency, or ordering error rises quickly.&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;Intent Compression Ratio(ICR)&lt;/strong&gt; starts to matter.&lt;/p&gt;

&lt;p&gt;High ICR becomes a prerequisite for agentic readiness.&lt;/p&gt;

&lt;h3&gt;
  
  
  kubectl apply Was a Hint
&lt;/h3&gt;

&lt;p&gt;We’ve seen this pattern before.&lt;/p&gt;

&lt;p&gt;kubectl apply didn’t simplify Kubernetes.&lt;/p&gt;

&lt;p&gt;It changed the interface.&lt;/p&gt;

&lt;p&gt;From:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Step-by-step execution&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To intent:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Here is the desired state.”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And the system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Builds the dependency graph&lt;/li&gt;
&lt;li&gt;Determines ordering&lt;/li&gt;
&lt;li&gt;Reconciles toward the desired state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It doesn’t remove complexity.&lt;/p&gt;

&lt;p&gt;It &lt;strong&gt;absorbs&lt;/strong&gt; the graph.&lt;/p&gt;

&lt;h3&gt;
  
  
  But We Never Measured the Absorption
&lt;/h3&gt;

&lt;p&gt;We say:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Intent-driven&lt;/li&gt;
&lt;li&gt;AI agents&lt;/li&gt;
&lt;li&gt;Skills&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But we don’t ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;How much complexity moved from the developer to the system?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s the  &lt;strong&gt;gap&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Intent Compression Ratio
&lt;/h3&gt;

&lt;p&gt;I’ve started calling this &lt;strong&gt;Intent Compression Ratio (ICR)&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A way to measure how much execution complexity is collapsed into intent.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To quantify this, we need a way to measure the “work” the system is doing for us.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ops&lt;/strong&gt;  : Are the &lt;em&gt;total required operations&lt;/em&gt; every distinct state-changing API call e.g. IAM binding, network rule, object creation, policy attachment, or validation step.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Intent expressions&lt;/strong&gt; are the &lt;em&gt;semantic&lt;/em&gt; &lt;em&gt;goals&lt;/em&gt; defined by the user.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuz9v8kscm21qrgct5kk3.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuz9v8kscm21qrgct5kk3.png" alt="Intent expressions" width="284" height="56"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A system with an ICR of 1 is just a wrapper.&lt;/p&gt;

&lt;p&gt;A system with an ICR of 10 is an architectural partner.&lt;/p&gt;

&lt;p&gt;At first glance, this looks like productivity.&lt;/p&gt;

&lt;p&gt;It isn’t.&lt;/p&gt;

&lt;p&gt;It measures who owns the system’s complexity.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Actually Gets Compressed
&lt;/h3&gt;

&lt;p&gt;Not just steps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cognitive load&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The developer no longer tracks ordering or dependencies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dependency graph&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The system constructs and executes the DAG.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Desired state&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
The system ensures correctness of what is being built, not just how.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Failure surface&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Fewer invalid states. Fewer silent failures.&lt;/p&gt;

&lt;p&gt;Higher ICR doesn’t just mean faster.&lt;/p&gt;

&lt;p&gt;It means &lt;strong&gt;safer&lt;/strong&gt; and more &lt;strong&gt;predictable&lt;/strong&gt; systems.&lt;/p&gt;

&lt;h3&gt;
  
  
  ICR in Action
&lt;/h3&gt;

&lt;p&gt;Let’s ground this with a few examples from the Snowflake platform.&lt;/p&gt;

&lt;p&gt;Snowflake is a concrete example but &lt;strong&gt;Intent Compression Ratio is the general idea.&lt;/strong&gt; I use &lt;a href="https://docs.snowflake.com/en/user-guide/cortex-code/cortex-code-cli" rel="noopener noreferrer"&gt;Cortex Code&lt;/a&gt; as an Agentic Coding tool &lt;strong&gt;proof point.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The pattern is broader than any one platform: whenever developers have to coordinate object creation, dependency ordering, policy enforcement, and desired state, there is an opportunity to compress the graph into intent.&lt;/p&gt;

&lt;h3&gt;
  
  
  Programmatic Access Token
&lt;/h3&gt;

&lt;p&gt;Intent:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Deploy a Google connector with&lt;/em&gt; &lt;a href="https://docs.snowflake.com/en/user-guide/data-integration/openflow/about" rel="noopener noreferrer"&gt;&lt;em&gt;Openflow&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Underlying reality:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create service user
&lt;/li&gt;
&lt;li&gt;Create service role
&lt;/li&gt;
&lt;li&gt;Grant role to user
&lt;/li&gt;
&lt;li&gt;Create network rule
&lt;/li&gt;
&lt;li&gt;Create network policy
&lt;/li&gt;
&lt;li&gt;Attach network policy to user
&lt;/li&gt;
&lt;li&gt;Create authentication policy
&lt;/li&gt;
&lt;li&gt;Attach authentication policy to user
&lt;/li&gt;
&lt;li&gt;Configure PAT policy constraints
&lt;/li&gt;
&lt;li&gt;Generate PAT
&lt;/li&gt;
&lt;li&gt;Store PAT securely for client usage
&lt;/li&gt;
&lt;li&gt;Validate token exchange via &lt;a href="https://nipyapi.readthedocs.io/en/latest/" rel="noopener noreferrer"&gt;Apache NiPyAPI&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;ICR ≈&lt;/strong&gt;  &lt;strong&gt;12 Ops / 1 intent = 12&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Or expressed as intent compression:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1 intent : 12 Ops&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is not step reduction.&lt;/p&gt;

&lt;p&gt;This is dependency graph compression.&lt;/p&gt;

&lt;h3&gt;
  
  
  Network Access
&lt;/h3&gt;

&lt;p&gt;Intent:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Allow access to googleapis.com.”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Underlying reality:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Rule definition&lt;/li&gt;
&lt;li&gt;Policy creation&lt;/li&gt;
&lt;li&gt;Attachment&lt;/li&gt;
&lt;li&gt;Grants&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;ICR ≈ 4 Ops / 1 intent = 4&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Or:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1 intent : 4 Ops&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  External Volume
&lt;/h3&gt;

&lt;p&gt;Intent:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Set up an Iceberg table with Snowflake.”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Underlying reality:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Storage integration&lt;/li&gt;
&lt;li&gt;IAM configuration&lt;/li&gt;
&lt;li&gt;External bindings&lt;/li&gt;
&lt;li&gt;Volume configuration&lt;/li&gt;
&lt;li&gt;Access validation&lt;/li&gt;
&lt;li&gt;Table setup&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;ICR ≈ 6 Ops / 1 intent = 6&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Or:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1 intent : 6 Ops&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Where Skills and AI Agents Fit
&lt;/h3&gt;

&lt;p&gt;This becomes critical in an AI-driven world.&lt;/p&gt;

&lt;p&gt;AI agents are not good at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Long procedural chains&lt;/li&gt;
&lt;li&gt;Fragile ordering&lt;/li&gt;
&lt;li&gt;Implicit dependencies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They are good at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Intent&lt;/li&gt;
&lt;li&gt;Bounded abstractions&lt;/li&gt;
&lt;li&gt;Repeatable execution units&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where skills come in.&lt;/p&gt;

&lt;p&gt;A skill is not just automation.&lt;/p&gt;

&lt;p&gt;It is a &lt;strong&gt;compressed execution graph with guarantees&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdgwp02359oztpcp6r70i.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdgwp02359oztpcp6r70i.png" alt="CEG" width="800" height="375"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;A skill compresses the execution graph behind a single expression of intent.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Whether implemented via Cortex Code or any other agentic system, a skill:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Encodes ordering&lt;/li&gt;
&lt;li&gt;Enforces constraints&lt;/li&gt;
&lt;li&gt;Ensures the correct desired state&lt;/li&gt;
&lt;li&gt;Handles sensitive steps, such as token handling, safely&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So when an agent executes:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Deploy a connector with Openflow.”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It doesn’t reason through 12 Ops.&lt;/p&gt;

&lt;p&gt;It invokes a single semantic unit.&lt;/p&gt;

&lt;p&gt;ICR becomes a proxy for how usable a system is for agents.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Tradeoff
&lt;/h3&gt;

&lt;p&gt;Not all compression is good.&lt;/p&gt;

&lt;h3&gt;
  
  
  Too Much Compression: Opaque Systems
&lt;/h3&gt;

&lt;p&gt;You run:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Deploy my connector.”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It works — until it doesn’t.&lt;/p&gt;

&lt;p&gt;Now the connector fails to authenticate.&lt;/p&gt;

&lt;p&gt;You don’t know which role was created.&lt;br&gt;&lt;br&gt;
You don’t know which policy was applied.&lt;br&gt;&lt;br&gt;
You don’t know if the network rule exists.&lt;br&gt;&lt;br&gt;
You don’t know whether the PAT was generated under the right constraints.&lt;/p&gt;

&lt;p&gt;You try to debug.&lt;/p&gt;

&lt;p&gt;But there is no visibility into intermediate steps.&lt;br&gt;&lt;br&gt;
There is no way to fix just one part.&lt;br&gt;&lt;br&gt;
Everything is hidden behind the abstraction.&lt;/p&gt;

&lt;p&gt;So you abandon it and go manual.&lt;/p&gt;

&lt;p&gt;High ICR.&lt;br&gt;&lt;br&gt;
Zero observability.&lt;/p&gt;

&lt;p&gt;That is not effective compression.&lt;/p&gt;

&lt;p&gt;That is opacity.&lt;/p&gt;

&lt;h3&gt;
  
  
  Too Little Compression: Fully Manual Systems
&lt;/h3&gt;

&lt;p&gt;Now take the opposite extreme.&lt;/p&gt;

&lt;p&gt;You manually create everything:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User&lt;/li&gt;
&lt;li&gt;Role&lt;/li&gt;
&lt;li&gt;Grants&lt;/li&gt;
&lt;li&gt;Network rule&lt;/li&gt;
&lt;li&gt;Network policy&lt;/li&gt;
&lt;li&gt;Auth policy&lt;/li&gt;
&lt;li&gt;Token&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Everything is visible.&lt;/p&gt;

&lt;p&gt;But now you own everything.&lt;/p&gt;

&lt;p&gt;You attach the wrong policy.&lt;br&gt;&lt;br&gt;
Or attach it in the wrong order.&lt;br&gt;&lt;br&gt;
Or bind the wrong role.&lt;br&gt;&lt;br&gt;
Or generate the token before the constraints are actually in place.&lt;/p&gt;

&lt;p&gt;Nothing errors.&lt;/p&gt;

&lt;p&gt;Your PAT is generated.&lt;br&gt;&lt;br&gt;
Your connector is deployed.&lt;/p&gt;

&lt;p&gt;But it doesn’t work.&lt;/p&gt;

&lt;p&gt;Debugging spans identity, network, and auth layers.&lt;/p&gt;

&lt;p&gt;Full control.&lt;br&gt;&lt;br&gt;
Full responsibility.&lt;/p&gt;

&lt;p&gt;That is not simplicity.&lt;/p&gt;

&lt;p&gt;That is exposed complexity.&lt;/p&gt;

&lt;h3&gt;
  
  
  Glass Box Compression
&lt;/h3&gt;

&lt;p&gt;The solution to opacity is not to go back to manual scripts.&lt;/p&gt;

&lt;p&gt;It is observable intent.&lt;/p&gt;

&lt;p&gt;I think of this as &lt;strong&gt;Glass Box Compression&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Unlike a black box, where the system performs magic and leaves you clueless when it breaks, a glass box system absorbs complexity while remaining transparent.&lt;/p&gt;

&lt;p&gt;Now consider a well-designed skill:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“Deploy a connector with Openflow.”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It executes the full dependency graph.&lt;br&gt;&lt;br&gt;
It enforces ordering.&lt;br&gt;&lt;br&gt;
It validates desired state.&lt;br&gt;&lt;br&gt;
It exposes what it created.&lt;/p&gt;

&lt;p&gt;And when something fails, it tells you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What failed&lt;/li&gt;
&lt;li&gt;Why it failed&lt;/li&gt;
&lt;li&gt;What was expected&lt;/li&gt;
&lt;li&gt;What can be retried safely&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can inspect the graph.&lt;br&gt;&lt;br&gt;
You can override specific parts.&lt;br&gt;&lt;br&gt;
You can re-run safely.&lt;/p&gt;

&lt;p&gt;This is high ICR with visibility.&lt;/p&gt;

&lt;p&gt;That is effective compression.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Shift
&lt;/h3&gt;

&lt;p&gt;We used to optimize for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Performance&lt;/li&gt;
&lt;li&gt;Scale&lt;/li&gt;
&lt;li&gt;Reliability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now we also optimize for:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;How much complexity the system can safely absorb.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Because in an intent-driven world:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Developers express goals&lt;/li&gt;
&lt;li&gt;AI agents invoke abstractions&lt;/li&gt;
&lt;li&gt;Systems execute graphs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The interface moves closer to intent.&lt;/p&gt;

&lt;p&gt;The execution moves deeper into the system.&lt;/p&gt;

&lt;p&gt;And the value shifts from:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“How many steps can I automate?”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“How much complexity can I safely stop thinking about?”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Closing Thought
&lt;/h3&gt;

&lt;p&gt;The question is no longer:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“What can this system do?”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;“How much of the system can you safely not think about?”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is the real power of intent.&lt;/p&gt;

&lt;p&gt;And that is what &lt;strong&gt;Intent Compression Ratio&lt;/strong&gt; begins to measure.&lt;/p&gt;

&lt;p&gt;This brings the series full circle.&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://blogs.kameshs.dev/infrastructure-as-intent-the-field-velocity-blueprint-e6217ef30f14" rel="noopener noreferrer"&gt;&lt;strong&gt;Infrastructure as Intent&lt;/strong&gt;&lt;/a&gt;, I argued that infrastructure is moving from imperative execution toward declarative intent: developers should describe the outcome, not manually orchestrate every step.&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://blogs.kameshs.dev/the-ghost-in-the-machine-why-ai-needs-the-spirit-of-uml-0d8864e583e2" rel="noopener noreferrer"&gt;&lt;strong&gt;The Ghost in the Machine&lt;/strong&gt;&lt;/a&gt;, I explored why intent still needs structure. We need the “Spirit of UML” — not necessarily UML diagrams themselves, but a way to model relationships, dependencies, and constraints before systems can safely automate them.&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://blogs.kameshs.dev/intent-driven-development-the-shift-developers-cant-ignore-ef434f94d56c" rel="noopener noreferrer"&gt;&lt;strong&gt;Intent-Driven Development&lt;/strong&gt;&lt;/a&gt;, I looked at the developer shift: from writing every instruction to shaping the intent that AI systems and platforms can execute.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Intent Compression Ratio&lt;/strong&gt; connects those ideas.&lt;/p&gt;

&lt;p&gt;If intent is the interface, and relationships are the hidden graph, then ICR asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;How much of that graph can the system safely absorb?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is the bridge from philosophy to measurement.&lt;/p&gt;

&lt;p&gt;In the next part of this series, I’ll look at how to build high-ICR skills into custom AI agents.&lt;/p&gt;

&lt;h3&gt;
  
  
  About the Author
&lt;/h3&gt;

&lt;p&gt;Kamesh Sampath is a Developer Advocate at Snowflake, an author, and a long-time open-source contributor with 25+ years in enterprise software. He works across data engineering and AI with developer communities, helping practitioners turn modern data platforms into systems that hold up in production.&lt;/p&gt;

&lt;p&gt;Through talks, writing, and hands-on demos, Kamesh makes cloud, data, and AI topics easier to understand and apply — grounded in real-world constraints. His sessions mix deep technical detail with practical patterns that developers and data teams can apply right away.&lt;/p&gt;

&lt;p&gt;Lately, he has been speaking about Apache NiFi, Snowflake Openflow, Snowflake Cortex, and PostgreSQL.&lt;/p&gt;

&lt;p&gt;He believes technology becomes powerful when it is shared, taught, and built together.&lt;/p&gt;

&lt;p&gt;GitHub | LinkedIn | Blog | X&lt;/p&gt;

</description>
      <category>ai</category>
      <category>devtools</category>
      <category>agents</category>
      <category>sdlc</category>
    </item>
    <item>
      <title>Intent Driven Development: The Shift Developers Can’t Ignore</title>
      <dc:creator>Kamesh Sampath</dc:creator>
      <pubDate>Fri, 17 Apr 2026 03:46:01 +0000</pubDate>
      <link>https://dev.to/kameshsampath/intent-driven-development-the-shift-developers-cant-ignore-4e67</link>
      <guid>https://dev.to/kameshsampath/intent-driven-development-the-shift-developers-cant-ignore-4e67</guid>
      <description>&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7s93e67gmxu1x13fq5ny.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7s93e67gmxu1x13fq5ny.png" alt="Intent Driven Development" width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;We spent decades writing code for machines. Now we need to express intent for them.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;There’s a quiet anxiety in software development right now.&lt;/p&gt;

&lt;p&gt;If AI can write code… where does that leave developers?&lt;/p&gt;

&lt;p&gt;The answer is simpler and more uncomfortable than it seems.&lt;/p&gt;

&lt;p&gt;Builders are not becoming obsolete.&lt;br&gt;&lt;br&gt;
They are becoming &lt;strong&gt;more important&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Because in a world where machines can generate code, the real bottleneck is no longer syntax.&lt;/p&gt;

&lt;p&gt;It is &lt;strong&gt;clarity of intent&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;AI is not replacing developers.&lt;br&gt;&lt;br&gt;
It is amplifying them.&lt;/p&gt;

&lt;p&gt;A vague developer with AI produces noise.&lt;br&gt;&lt;br&gt;
A precise developer with AI produces systems.&lt;/p&gt;

&lt;p&gt;The leverage has shifted but the responsibility has not.&lt;/p&gt;

&lt;p&gt;Developers who can express intent are still in control.&lt;/p&gt;

&lt;p&gt;But the interface has changed.&lt;/p&gt;

&lt;p&gt;We are no longer just writing code.&lt;br&gt;&lt;br&gt;
We are &lt;strong&gt;shaping what systems should do with just pure natural language&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This shift doesn’t come out of nowhere.&lt;/p&gt;

&lt;p&gt;My previous article on &lt;a href="https://blogs.kameshs.dev/infrastructure-as-intent-the-field-velocity-blueprint-e6217ef30f14" rel="noopener noreferrer"&gt;Infrastructure as Intent&lt;/a&gt;, I explored how systems are moving toward declared outcomes over explicit instructions.&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://blogs.kameshs.dev/the-ghost-in-the-machine-why-ai-needs-the-spirit-of-uml-0d8864e583e2" rel="noopener noreferrer"&gt;The Spirit of UML&lt;/a&gt;, I argued that abstraction is becoming essential again in the age of AI.&lt;/p&gt;

&lt;p&gt;In this article, I propose that &lt;strong&gt;I&lt;/strong&gt; ntent &lt;strong&gt;D&lt;/strong&gt; riven &lt;strong&gt;D&lt;/strong&gt; evelopment(IDD) is where these ideas meet in practice.&lt;/p&gt;

&lt;h3&gt;
  
  
  We’re Still Thinking Like Syntaxists
&lt;/h3&gt;

&lt;p&gt;Even with AI tools everywhere, most developers still:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Write code line by line&lt;/li&gt;
&lt;li&gt;Focus on syntax and structure&lt;/li&gt;
&lt;li&gt;Debug implementation details&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI becomes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Faster autocomplete&lt;/li&gt;
&lt;li&gt;Better Stack Overflow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But that misses the point.&lt;/p&gt;

&lt;p&gt;The real shift is not AI writing code.&lt;br&gt;&lt;br&gt;
It is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Developers expressing intent clearly enough that machines can realize it.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  From Syntax to Semantics
&lt;/h3&gt;

&lt;p&gt;We were trained to be &lt;em&gt;syntaxists&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;We think in functions, APIs, and control flow.&lt;/p&gt;

&lt;p&gt;Intent Driven Development requires semanticists:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Intent&lt;/li&gt;
&lt;li&gt;Constraints&lt;/li&gt;
&lt;li&gt;Context&lt;/li&gt;
&lt;li&gt;Outcomes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Code doesn’t disappear.&lt;br&gt;&lt;br&gt;
But it stops being the starting point.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Intent becomes the source. Code becomes the artifact.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Writing Better Prompts is Writing Better Software
&lt;/h3&gt;

&lt;p&gt;In this world, prompts are not casual inputs.&lt;br&gt;&lt;br&gt;
They are &lt;strong&gt;design artifacts&lt;/strong&gt;.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Build a dashboard&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Intent-driven:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Build a Streamlit dashboard using Snowflake TPCH data. Show revenue trends over time, allow filtering by region and customer segment, and generate natural language insights. Keep the UI minimal and ensure queries are efficient.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The difference is &lt;strong&gt;&lt;em&gt;precision&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Real Example: From Intent to App (Cortex + Streamlit)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3qa6ia3svdul737jg7qr.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3qa6ia3svdul737jg7qr.png" alt="A Real Example" width="371" height="900"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Development Loop&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Start with intent that clearly defines the end outcomes:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Build a Streamlit dashboard using Snowflake TPCH data.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Show revenue trends over time&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Allow filtering by region and customer segment&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Use Cortex to generate natural language insights&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Keep the UI minimal but interactive&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Ensure queries are efficient and reusable&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No boilerplate. No step-by-step instructions just clear intents.&lt;/p&gt;

&lt;p&gt;Using tools like Cortex Code, this intent can translate into:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Snowflake queries over TPCH tables&lt;/li&gt;
&lt;li&gt;Aggregations for revenue trends&lt;/li&gt;
&lt;li&gt;A Streamlit UI with filters and charts&lt;/li&gt;
&lt;li&gt;LLM-generated summaries like: “Revenue dipped in Q3 due to decline in APAC region”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You didn’t handwrite everything.&lt;br&gt;&lt;br&gt;
You guided the system with intent.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where Developers Still Matter
&lt;/h3&gt;

&lt;p&gt;The first version won’t be perfect.&lt;/p&gt;

&lt;p&gt;Maybe the query is inefficient.&lt;br&gt;&lt;br&gt;
Maybe the chart is unclear.&lt;br&gt;&lt;br&gt;
Maybe the insights are generic.&lt;/p&gt;

&lt;p&gt;You refine the intent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Optimize queries for large datasets&lt;/li&gt;
&lt;li&gt;Make insights specific to region trends&lt;/li&gt;
&lt;li&gt;Add anomaly detection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each iteration improves the system without dropping to low-level code immediately.&lt;/p&gt;

&lt;h3&gt;
  
  
  But… How Do You Know It’s Good?
&lt;/h3&gt;

&lt;p&gt;You build something like this and think:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Looks right… but can I trust it?”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is where most AI-driven apps fail.&lt;/p&gt;

&lt;p&gt;Not in building but in &lt;strong&gt;knowing whether they’re accurate and efficient.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding a Evaluation Layer with TruLens
&lt;/h3&gt;

&lt;p&gt;Intent Driven Development needs evaluation.&lt;/p&gt;

&lt;p&gt;Frameworks like TruLens make this practical.&lt;/p&gt;

&lt;p&gt;They help measure whether your system aligns with your intent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Context Relevance&lt;/strong&gt; → Is the system finding the right data?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Groundedness&lt;/strong&gt; → Are insights tied to actual data?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Answer Relevance&lt;/strong&gt; → Is the system completing its goal?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plan Quality →&lt;/strong&gt; Is the agent forming a plan that is optimal for the user’s goal?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tool Selection →&lt;/strong&gt; Is the agent choosing the right tools for each task?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Plan Adherence →&lt;/strong&gt; Does the agent follow its own plan, or drift mid-execution?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tool Calling →&lt;/strong&gt; Are tools being called correctly and with the right inputs?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logical Consistency →&lt;/strong&gt; Does the agent maintain coherent reasoning across steps?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Execution Efficiency →&lt;/strong&gt; Is the agent solving the task with minimal steps, cost, and latency?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These aren’t just metrics.&lt;/p&gt;

&lt;p&gt;They are checks on your intent and the system’s ability to complete your goals.&lt;/p&gt;

&lt;h3&gt;
  
  
  The New Loop
&lt;/h3&gt;

&lt;p&gt;Intent Driven Development changes the workflow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Define intent&lt;/li&gt;
&lt;li&gt;Generate system&lt;/li&gt;
&lt;li&gt;Measure results&lt;/li&gt;
&lt;li&gt;Refine intent&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You’re not just debugging code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You’re debugging meaning.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why This Matters Now
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;AI can act on intent&lt;/li&gt;
&lt;li&gt;Systems are too complex to handcraft&lt;/li&gt;
&lt;li&gt;The bottleneck is idea → implementation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;IDD reduces that gap.&lt;/p&gt;

&lt;p&gt;It lets developers operate closer to the problem than the plumbing.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Developer Shift
&lt;/h3&gt;

&lt;p&gt;The next generation of developers will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Express constraints clearly&lt;/li&gt;
&lt;li&gt;Structure intent precisely&lt;/li&gt;
&lt;li&gt;Guide AI systems&lt;/li&gt;
&lt;li&gt;Measure quality continuously&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The best developers won’t write the most code.&lt;/p&gt;

&lt;p&gt;They’ll express the clearest intent and validate it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Closing
&lt;/h3&gt;

&lt;p&gt;We taught machines to understand syntax.&lt;/p&gt;

&lt;p&gt;Now we need to lead them with intent.&lt;/p&gt;

&lt;p&gt;AI hasn’t taken control away from developers.&lt;/p&gt;

&lt;p&gt;It has raised the bar for what control means.&lt;/p&gt;

&lt;p&gt;The developers who thrive in this shift won’t be the ones who write the most code.&lt;/p&gt;

&lt;p&gt;They’ll be the ones who can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;express intent clearly&lt;/li&gt;
&lt;li&gt;define constraints precisely&lt;/li&gt;
&lt;li&gt;And validate outcomes rigorously&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because in this new model, code is no longer the source of truth.&lt;/p&gt;

&lt;p&gt;Intent is.&lt;/p&gt;

&lt;p&gt;AI is powerful but it is still just an executor.&lt;/p&gt;

&lt;p&gt;The developer remains the authority.&lt;/p&gt;

&lt;p&gt;And like any good system, the quality of the output will always depend on the clarity of the input.&lt;/p&gt;

&lt;p&gt;It starts with something simple.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The next intent you write.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Resources
&lt;/h3&gt;

&lt;p&gt;If you want to explore Intent Driven Development hands-on, here are a few starting points.&lt;/p&gt;

&lt;h4&gt;
  
  
  Try the Intent Yourself
&lt;/h4&gt;

&lt;p&gt;Use this prompt with Cortex Code (or a similar tool) and iterate on it:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Intent Prompt:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Build a Streamlit dashboard using Snowflake TPCH data.&lt;/p&gt;

&lt;p&gt;Requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Show revenue trends over time&lt;/li&gt;
&lt;li&gt;Allow filtering by region and customer segment&lt;/li&gt;
&lt;li&gt;Use semantic queries over Snowflake tables&lt;/li&gt;
&lt;li&gt;Generate natural language insights for trends and anomalies&lt;/li&gt;
&lt;li&gt;Ensure all insights are grounded in actual query results&lt;/li&gt;
&lt;li&gt;Keep the UI minimal, fast, and interactive&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Constraints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Optimize queries for large datasets&lt;/li&gt;
&lt;li&gt;Structure the code for reuse and clarity&lt;/li&gt;
&lt;li&gt;Return both data visualizations and textual summaries&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Streamlit app code&lt;/li&gt;
&lt;li&gt;Snowflake queries used&lt;/li&gt;
&lt;li&gt;Example insights generated from the data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Start with this, then refine the intent.&lt;/p&gt;

&lt;p&gt;That’s the practice: improving the clarity of what you want the system to do.&lt;/p&gt;

&lt;p&gt;👉 Check out the TruLens cheatsheet: &lt;a href="https://github.com/Snowflake-Labs/sf-cheatsheets/blob/main/rag-evaluation-cheatsheet.md" rel="noopener noreferrer"&gt;https://github.com/Snowflake-Labs/sf-cheatsheets/blob/main/rag-evaluation-cheatsheet.md&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Tools
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.snowflake.com/en/user-guide/cortex-code/cortex-code-cli" rel="noopener noreferrer"&gt;Cortex Code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://streamlit.io" rel="noopener noreferrer"&gt;Streamlit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://signup.snowflake.com/" rel="noopener noreferrer"&gt;Snowflake&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://truelens.org" rel="noopener noreferrer"&gt;TruLens&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>sdlc</category>
      <category>machinelearning</category>
      <category>devrel</category>
    </item>
    <item>
      <title>The Ghost in the Machine: Why AI Needs the Spirit of UML</title>
      <dc:creator>Kamesh Sampath</dc:creator>
      <pubDate>Sat, 28 Feb 2026 13:48:19 +0000</pubDate>
      <link>https://dev.to/kameshsampath/the-ghost-in-the-machine-why-ai-needs-the-spirit-of-uml-1359</link>
      <guid>https://dev.to/kameshsampath/the-ghost-in-the-machine-why-ai-needs-the-spirit-of-uml-1359</guid>
      <description>&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F729wvb18px3zcwod8v0s.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F729wvb18px3zcwod8v0s.png" alt="The Ghost in the Machine" width="800" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;AI can generate code at 10x speed. It still doesn’t understand the systems it’s building.&lt;/p&gt;

&lt;p&gt;This story is about why we need to revive the spirit of&lt;a href="https://en.wikipedia.org/wiki/Unified_Modeling_Language" rel="noopener noreferrer"&gt;Unified Modelling Language( &lt;strong&gt;UML&lt;/strong&gt; )&lt;/a&gt; — not as diagrams, but as living infrastructure.&lt;/p&gt;

&lt;p&gt;Back then, the hot trend was&lt;a href="https://en.wikipedia.org/wiki/Model-driven_engineering" rel="noopener noreferrer"&gt;Model-Driven Development &lt;strong&gt;(MDD)&lt;/strong&gt;&lt;/a&gt; — generating code from models. UML was the flagship: Class Diagrams, Sequence Diagrams, the whole catalog. The belief was simple: if the model was correct, the system would be correct.&lt;/p&gt;

&lt;p&gt;We were wrong.&lt;/p&gt;

&lt;p&gt;UML didn’t fail because modeling was useless. It failed because of the &lt;strong&gt;Sync Tax&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You draw a class diagram. Rational Rose generates clean code. You ship it. QA finds bugs. Hotfixes go in. Production diverges. The model is now stale.&lt;/p&gt;

&lt;p&gt;Keeping diagrams and code aligned becomes real work. Expensive work. The tax exceeds the value. So teams stop paying it.&lt;/p&gt;

&lt;p&gt;We declared, “The code is the documentation,” and moved on.&lt;/p&gt;

&lt;p&gt;Starting to sound familiar?&lt;/p&gt;

&lt;p&gt;If you ask me, we are back in the MDD era. We’ve just rebranded it as &lt;strong&gt;AI-Driven Development&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The diagram is gone. The model remains. Only now, instead of &lt;strong&gt;Sync Tax&lt;/strong&gt; , we pay the &lt;strong&gt;Hallucination Tax&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;AI agents generate code at unprecedented speed. Ask, “Generate a Snowflake pipeline to ingest customer events,” and it produces SQL, tasks, maybe even a clean dbt model in seconds.&lt;/p&gt;

&lt;p&gt;But the real question is: Does it understand the system it is operating in?&lt;/p&gt;

&lt;p&gt;Specifically, when you give it that prompt, does it see the whole picture?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your warehouse sizing and cost guardrails?&lt;/li&gt;
&lt;li&gt;Your RBAC model and masking policies?&lt;/li&gt;
&lt;li&gt;Which schema is production-certified versus experimental?&lt;/li&gt;
&lt;li&gt;Which data is PII and which roles are allowed to see it?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then there’s the &lt;strong&gt;Context Gap&lt;/strong&gt;  — the ritual of re-explaining your infrastructure to an agent with limited working memory. Every new chat resets shared understanding. Yes, there are hacks. But none of them feel native.&lt;/p&gt;

&lt;p&gt;The spirit of modeling was never about diagrams. It was about shared context.&lt;/p&gt;

&lt;p&gt;AI has the muscle. It lacks shared context.&lt;/p&gt;

&lt;p&gt;So here’s the twist: UML and AI are two halves of a broken whole.&lt;/p&gt;

&lt;p&gt;UML was too rigid for humans to maintain. AI is too fluid for systems to trust.&lt;/p&gt;

&lt;p&gt;To solve the&lt;a href="https://blogs.kameshs.dev/infrastructure-as-intent-the-field-velocity-blueprint-e6217ef30f14" rel="noopener noreferrer"&gt;&lt;strong&gt;Field Velocity&lt;/strong&gt;&lt;/a&gt; problem, we don’t go back to 2005.&lt;/p&gt;

&lt;p&gt;We make AI pay the &lt;strong&gt;Sync Tax&lt;/strong&gt; for us.&lt;/p&gt;

&lt;p&gt;And the only way to do that is to encode intent as an enforceable structure.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Living Model: From “Pretty Picture” to “Policy”
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9kw46ym8jedg3mroqsca.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9kw46ym8jedg3mroqsca.png" alt="Operationalizing Human Intent" width="800" height="800"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Operationalizing Human Intent: Our conceptual model for combining an AI Agent with a central knowledge repository of Architectural Memory to enforce security, governance, and infrastructure best practices for automated and compliant code generation.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In my earlier blog on &lt;strong&gt;I&lt;/strong&gt; &lt;a href="https://blogs.kameshs.dev/infrastructure-as-intent-the-field-velocity-blueprint-e6217ef30f14" rel="noopener noreferrer"&gt;&lt;strong&gt;nfrastructure-as-Intent&lt;/strong&gt;&lt;/a&gt;, I wrote about how human expertise and experience can be carved into agentic &lt;strong&gt;Skills&lt;/strong&gt; &lt;em&gt;(In Part 1, we defined Skills as the codified expertise and human experience that turn operators into mentors for AI agents.)&lt;/em&gt; ** ** , turning each of us from operators into mentors.&lt;/p&gt;

&lt;p&gt;That shift forces us to stop authoring static models and start inferring living ones.&lt;/p&gt;

&lt;p&gt;The truth of your system already exists — scattered across scripts, RBAC definitions, masking policies, and CI/CD pipelines.&lt;/p&gt;

&lt;p&gt;So why does AI still hallucinate?&lt;/p&gt;

&lt;p&gt;Because of the &lt;strong&gt;Context Gap&lt;/strong&gt;  — the absence of shared context.&lt;/p&gt;

&lt;p&gt;Here is how we revive the UML spirit: by turning Skills into the rules of engagement for our AI agents.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Guardrail Effect
&lt;/h3&gt;

&lt;p&gt;When we practiced UML, we followed the structure. First system architecture. Then sequence diagrams. Then class diagrams. Step by step, we built a shared understanding.&lt;/p&gt;

&lt;p&gt;In the AI era, shared understanding becomes shared constraints.&lt;/p&gt;

&lt;p&gt;Instead of executing a prompt literally, the AI must query the Skills.&lt;/p&gt;

&lt;p&gt;If a Skill declares, “All customer data requires masking primitive X,” that declaration becomes an enforceable structure. The agent generates within it, not around it. The constraint is applied at the point of creation.&lt;/p&gt;

&lt;p&gt;That is the spirit of UML — reborn as an executable policy.&lt;/p&gt;

&lt;p&gt;Policy is what machines can execute. Intent is what they can reason about.&lt;/p&gt;

&lt;h3&gt;
  
  
  Semantic Reasoning
&lt;/h3&gt;

&lt;p&gt;Shared constraints unlock something UML never could: semantic reasoning.&lt;/p&gt;

&lt;p&gt;UML provided syntactic structure. The reasoning lived in our heads.&lt;/p&gt;

&lt;p&gt;AI can reason — but only if we give it structure.&lt;/p&gt;

&lt;p&gt;Ask, “If I change this stream’s schema, who breaks?”&lt;/p&gt;

&lt;p&gt;The AI uses the Skill graph to simulate impact and produce a blast-radius report before a single ALTER TABLE runs.&lt;/p&gt;

&lt;p&gt;That is the difference between generation and understanding.&lt;/p&gt;

&lt;p&gt;This is where intent stops being documentation and starts becoming infrastructure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Closing the Context Gap
&lt;/h3&gt;

&lt;p&gt;In my earlier post, I introduced the idea of a &lt;strong&gt;Shared Manifest&lt;/strong&gt;  — a persistent memory layer for AI agents. Not as a long prompt, but as structured Skills.&lt;/p&gt;

&lt;p&gt;With Skills, the agent carries &lt;strong&gt;Architectural Memory&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It knows your certified schemas. Your cost guardrails. Your intent. Because it operates inside the same world model as you.&lt;/p&gt;

&lt;p&gt;The Living Model is not documentation. It is infrastructure.&lt;/p&gt;

&lt;p&gt;This is &lt;strong&gt;Infrastructure-as-Intent&lt;/strong&gt; in action.&lt;/p&gt;

&lt;p&gt;We use the rigidity of the model to keep AI honest.&lt;/p&gt;

&lt;p&gt;We use the fluidity of AI to pay the &lt;strong&gt;Sync Tax&lt;/strong&gt;  — bringing the spirit of UML back as living infrastructure.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Call to Builders
&lt;/h3&gt;

&lt;p&gt;We don’t need a return to 2005-era static diagrams. We need an &lt;strong&gt;Architectural Memory&lt;/strong&gt; for our systems.&lt;/p&gt;

&lt;p&gt;Agentic AI tools have already defined the schema. Don’t panic about learning another DSL 🤣. It’s not one.&lt;/p&gt;

&lt;p&gt;It’s a disciplined Markdown. Clear English. Proper structure. The same rigor you apply when writing a design doc.&lt;/p&gt;

&lt;p&gt;Except now, that document is executable.&lt;/p&gt;

&lt;p&gt;It’s not documentation for humans alone. It is codified wisdom for agents.&lt;/p&gt;

&lt;p&gt;The era of blind velocity is over.&lt;/p&gt;

&lt;p&gt;It’s time to give the muscle a brain.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Visuals note: The conceptual diagrams in this post were generated by Google Gemini.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  About the Author
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Kamesh Sampath&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;is a Lead Developer Advocate at Snowflake, author, and long-time open-source contributor with 25+ years in enterprise software. He works across data engineering and AI with developer communities, helping practitioners turn modern data platforms into systems that hold up in production.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Through talks, writing, and hands-on demos, Kamesh makes cloud, data, and AI topics easier to understand and apply — grounded in real-world constraints. His sessions mix deep technical detail with practical patterns that developers and data teams can apply right away.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Lately, he’s been speaking about Apache NiFi (Snowflake Openflow), AI (Snowflake Cortex), and PostgreSQL.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;He believes technology becomes powerful when it is shared, taught, and built together.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kameshsampath" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; |&lt;a href="https://linkedin.com/in/kameshsampath" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; |&lt;a href="https://blogs.kameshs.dev/" rel="noopener noreferrer"&gt;Blog&lt;/a&gt; |&lt;a href="https://x.com/kamesh_sampath" rel="noopener noreferrer"&gt; X&lt;/a&gt;&lt;/p&gt;

</description>
      <category>platformengineering</category>
      <category>ai</category>
      <category>devops</category>
      <category>iac</category>
    </item>
    <item>
      <title>Infrastructure-as-Intent: The Field Velocity Blueprint</title>
      <dc:creator>Kamesh Sampath</dc:creator>
      <pubDate>Mon, 16 Feb 2026 16:45:10 +0000</pubDate>
      <link>https://dev.to/kameshsampath/infrastructure-as-intent-the-field-velocity-blueprint-ph4</link>
      <guid>https://dev.to/kameshsampath/infrastructure-as-intent-the-field-velocity-blueprint-ph4</guid>
      <description>&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjdtvuaa81bocqgainhq5.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjdtvuaa81bocqgainhq5.png" alt="Infrastructure-as-Intent" width="800" height="423"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Infrastructure-as-Intent: Bridging human creativity with AI precision to accelerate data value.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We ’ve spent years building automation pipelines to deploy infrastructure. We call it Infrastructure-as-Code (IaC) — whether that’s Terraform, Ansible, or even simple CLI scripts. It saves us from nightmares when we need consistency between where we develop and where we deploy. &lt;strong&gt;Development == Production&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But when Snowflake launched &lt;a href="https://www.snowflake.com/en/product/features/cortex-code/" rel="noopener noreferrer"&gt;Cortex Code&lt;/a&gt; — an AI coding agent designed for the Data Cloud — it sparked a new thought for me: why can’t we take IaC automation into its next phase? Instead of declaring how to build everything step by step, what if we simply declared the outcome we want?&lt;/p&gt;

&lt;p&gt;This idea wasn’t born out of nowhere. It came from my own attempts to modernize my scripts — snow-utils — a collection of utilities I built to repeatedly set up Snowflake environments for demos. They started as a way to eliminate the rinse-and-repeat plumbing work.&lt;/p&gt;

&lt;p&gt;The scripts solved the plumbing problem. But they introduced a different one: &lt;em&gt;remembering the right combination of parameters every single time&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;That frustration led me to a deeper pattern — one that could fundamentally change how we interact with cloud environments, and one that fits naturally into this new AI-assisted era.&lt;/p&gt;
&lt;h3&gt;
  
  
  The “Field Velocity” Problem
&lt;/h3&gt;

&lt;p&gt;So we found the problem, built a solution, and then refined it further — something that could take us into the next phase. But before we get there, let’s pause and ask: why does this even matter?&lt;/p&gt;

&lt;p&gt;The answer is simple and universal: &lt;strong&gt;speed&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We invented computers to help us do things faster. But as computer science evolved, the systems we built became increasingly complex. Somewhere along the way, speed started fighting complexity.&lt;/p&gt;

&lt;p&gt;That’s what I call the &lt;strong&gt;Field Velocity problem&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;What is it exactly?&lt;/p&gt;

&lt;p&gt;It’s the time it takes to go from a customer asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Can we query Snowflake-managed Iceberg tables from DuckDB?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;to a working, deployed proof of concept.&lt;/p&gt;

&lt;p&gt;If you look closely at the history of Infrastructure-as-Code, you’ll notice something consistent. The bottleneck is rarely the idea. It’s the plumbing.&lt;/p&gt;

&lt;p&gt;So our customer’s question will translate into following tasks(plumbing):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Configuring IAM roles – &amp;gt; Editing trust policies – &amp;gt; Setting up buckets. – &amp;gt; Creating network rules – &amp;gt; DDL Statements.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If I put it mathematically, we spend 90% of our time on plumbing and only 10% on the actual value.&lt;/p&gt;

&lt;p&gt;So the fix? Invert the ratio.&lt;/p&gt;

&lt;p&gt;That inversion is what I call &lt;strong&gt;Infrastructure-as-Intent&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Same wine. New bottle. 😉&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0e4y52mzjv574e5gg3fi.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0e4y52mzjv574e5gg3fi.png" alt="Field Velocity" width="800" height="383"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Field Velocity: Flipping the ratio with Infrastructure as Intent&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  The Evolution: &lt;strong&gt;From Power CLI to Atomic Primitives&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;I come from a strong Linux and infrastructure background, and I’m a die-hard CLI person. If something is repetitive, my instinct is to script it.&lt;/p&gt;

&lt;p&gt;That “Power CLI” reflex is what led me to write snow-utils.&lt;/p&gt;

&lt;p&gt;Let me explain with a simple example.&lt;/p&gt;

&lt;p&gt;Say I want to connect Snowflake to an AWS S3 bucket. Sounds straightforward. In reality, it looks like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Log into AWS Console → Create S3 bucket&lt;/li&gt;
&lt;li&gt;Create an IAM policy&lt;/li&gt;
&lt;li&gt;Create an IAM role and attach the policy&lt;/li&gt;
&lt;li&gt;Log into Snowflake → Create the EXTERNAL VOLUME&lt;/li&gt;
&lt;li&gt;Run DESCRIBE EXTERNAL VOLUME to hunt for AWS user ARN&lt;/li&gt;
&lt;li&gt;Go back to AWS → Edit the Trust Relationship JSON and paste those values&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And yes — to err is human. But one small typo in that trust policy JSON, or grabbing the wrong property from the Snowflake DESCRIBE output, can cost you hours of debugging before everything finally works.&lt;/p&gt;

&lt;p&gt;That’s when I decided to wrap this entire chain of interdependent steps into a single command.&lt;/p&gt;

&lt;p&gt;Instead of manually wiring everything together, I created a primitive that understood the sequence.&lt;/p&gt;

&lt;p&gt;Now, for the same task, it’s simply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;snow-utils extvolume:up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Done.&lt;/p&gt;

&lt;p&gt;One clean shot. Goal scored.&lt;/p&gt;

&lt;p&gt;Over time, it became deterministic. It worked every time — no manual hunting, no fragile copy-paste, no mysterious “Access Denied” errors.&lt;/p&gt;

&lt;p&gt;That’s when I realized something important: these weren’t just scripts anymore. They were &lt;strong&gt;atomic primitives&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3ylhvvtk00j94tadyad7.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3ylhvvtk00j94tadyad7.png" alt="Deconstruction" width="800" height="430"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Deconstruction: Moving from brittle, monolithic scripts to composable, reusable primitives.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  The Shift: From Operator to Mentor
&lt;/h3&gt;

&lt;p&gt;Once I had the primitives working reliably, I started asking a new question: why can’t this be more intelligent?&lt;/p&gt;

&lt;p&gt;Around that time, Snowflake announced Cortex Code. What caught my attention wasn’t just that it was an AI coding agent, but the concept of &lt;strong&gt;Skills&lt;/strong&gt;  — giving the agent structured capabilities to orchestrate tools and perform tasks in a more contextual way.&lt;/p&gt;

&lt;p&gt;That’s when I saw the transition from Infrastructure-as-Code (IaC) to Infrastructure-as-Intent (IaI) taking shape.&lt;/p&gt;

&lt;p&gt;Instead of keeping a mental checklist of parameters, flags, expiration rules, and policy combinations, why couldn’t I just express the intent and let the system handle the wiring?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Set up a Snowflake External Volume.”&lt;br&gt;&lt;br&gt;
“Create a Snowflake PAT.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It suddenly felt possible.&lt;/p&gt;

&lt;p&gt;But this wasn’t just about making things simpler. It was about changing roles.&lt;/p&gt;

&lt;p&gt;With IaC, I was the operator — running commands, supplying parameters, ensuring everything aligned.&lt;/p&gt;

&lt;p&gt;With IaI, I started becoming &lt;strong&gt;the&lt;/strong&gt;  mentor.&lt;/p&gt;

&lt;p&gt;I wasn’t just teaching syntax. I was embedding experience.&lt;/p&gt;

&lt;p&gt;Years of small production scars. Lessons from silent authentication failures. The instinct to validate IAM structures before applying them. The habit of forcing a dry run before destructive changes. The discipline of demanding explicit confirmation when something could break environments.&lt;/p&gt;

&lt;p&gt;That’s what I call &lt;strong&gt;codifying wisdom&lt;/strong&gt;  — capturing operational judgment and passing it into the system so it behaves the way I would.&lt;/p&gt;

&lt;p&gt;Let’s not fear AI. It doesn’t invent wisdom on its own — it executes what we mentor it to do.&lt;/p&gt;

&lt;p&gt;Intelligence still comes from somewhere.&lt;/p&gt;

&lt;p&gt;Let me make this concrete.&lt;/p&gt;

&lt;p&gt;Suppose I want to create a Snowflake &lt;strong&gt;Programmatic Access Token (PAT)&lt;/strong&gt;. Traditionally, that involves multiple careful steps: creating a service user, applying network restrictions, attaching the correct policies, defining expiration windows, and ensuring everything aligns securely.&lt;/p&gt;

&lt;p&gt;Instead of remembering every option and edge case, I wrote a simple markdown file called SKILLS and embedded all the logic behind the PAT primitive into it — including the commands and my opinions about how it should be done safely.&lt;/p&gt;

&lt;p&gt;Now all I need to tell Cortex Code is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Set me up a PAT that’s valid for 7 days and expires 30 days from now.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That’s it.&lt;/p&gt;

&lt;p&gt;No more remembering long chains of parameters. No wrappers around wrappers. No cognitive overhead.&lt;/p&gt;

&lt;p&gt;What emerged was a &lt;strong&gt;composable architecture&lt;/strong&gt;  — where the logic (snow-utils) is unbundled from the interface (Cortex Code).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;primitives&lt;/strong&gt; remain solid.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;skills&lt;/strong&gt; carry the experience.&lt;/li&gt;
&lt;li&gt;The interface interprets &lt;strong&gt;intent&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That separation is what turns automation into intent.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe1jqk4mi20mjk018q9la.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe1jqk4mi20mjk018q9la.png" alt="The New Workflow" width="800" height="418"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The New Workflow: The Human defines the “Skill” (intent &amp;amp; guardrails), and the AI handles the execution.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  The Pedagogical Pattern: Intentional Failure as a Feature
&lt;/h3&gt;

&lt;p&gt;When I spoke about intent in the previous section, I didn’t just mean my intent to run a set of commands or automation scripts. I had another intent in mind as well.&lt;/p&gt;

&lt;p&gt;Too many intents? I can already see an “Intent Overflow Exception” coming. 😉&lt;/p&gt;

&lt;p&gt;Jokes apart — as a Power CLI user, clear intent helps me execute tasks efficiently. But a mentor does more than execute. A mentor creates situations where you apply your skills across related areas. A mentor shapes understanding.&lt;/p&gt;

&lt;p&gt;As a Developer Advocate, I build demos, tutorials, and utilities like snow-utils. I usually share my GitHub repositories with a README explaining how to run the demo you just saw in my session.&lt;/p&gt;

&lt;p&gt;That works.&lt;/p&gt;

&lt;p&gt;But nothing matches personalized teaching — where the session leader’s experience, empathy, and small nuances surface naturally. The little warnings. The subtle explanations. The “watch this part carefully” moments.&lt;/p&gt;

&lt;p&gt;That’s a classic pedagogical pattern.&lt;/p&gt;

&lt;p&gt;Let me explain with the &lt;a href="https://github.com/kameshsampath/hirc-duckdb-demo" rel="noopener noreferrer"&gt;Horizontal Iceberg REST Catalog (HIRC) and DuckDB demo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;All you have to say now is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Deploy HIRC DuckDB demo.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But the real power isn’t just in deploying the environment. It’s in how the Skill is structured.&lt;/p&gt;

&lt;p&gt;I intentionally embedded a learning flow into it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Say what you are going to do&lt;/li&gt;
&lt;li&gt;Do it&lt;/li&gt;
&lt;li&gt;Let it fail&lt;/li&gt;
&lt;li&gt;Explain why it failed&lt;/li&gt;
&lt;li&gt;Fix it&lt;/li&gt;
&lt;li&gt;Show how it succeeds&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That pattern is deliberate.&lt;/p&gt;

&lt;p&gt;The goal isn’t just automation. It’s understanding.&lt;/p&gt;

&lt;p&gt;That’s the human part — and that doesn’t emerge automatically. You have to mentor it into the system.&lt;/p&gt;

&lt;p&gt;Now the Skill doesn’t just deploy infrastructure. It delivers a learning experience.&lt;/p&gt;
&lt;h3&gt;
  
  
  The “Recorder” Bonus: Intelligent &amp;amp; Interactive Reproduction
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2c4sbm5yc7qyqx2zu5xb.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2c4sbm5yc7qyqx2zu5xb.png" alt="Context Adaptation" width="800" height="437"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Context Adaptation: Transforming a manifest from “Works on my machine” (AWS) to “Works on your cloud” (Azure)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Since I’m documenting intent as a Skill, the natural next step was to share it.&lt;/p&gt;

&lt;p&gt;That’s how we normally share knowledge — notes, blogs like this, repositories, configuration files.&lt;/p&gt;

&lt;p&gt;So I asked myself: what if I wanted my product team to reproduce the exact same demo? Or reproduce a tricky bug?&lt;/p&gt;

&lt;p&gt;In a classic IaC world, I would share a configuration file. The other person would clone the repo, pull it down, and then start adjusting dozens of environment settings — region values, parameter overrides, warehouse sizes, credentials — before they could even run it.&lt;/p&gt;

&lt;p&gt;It works, but it assumes their environment matches mine.&lt;/p&gt;

&lt;p&gt;Now think about how humans do this.&lt;/p&gt;

&lt;p&gt;If I explain a setup to you, you don’t copy it blindly. You adapt it to your context. You change the region. You adjust the resource sizes. You map it to your naming conventions. You interpret the intent, not just the configuration.&lt;/p&gt;

&lt;p&gt;That’s exactly what the IaI pattern enables with shared manifests.&lt;/p&gt;

&lt;p&gt;When I share a manifest, I’m not just sharing a file. I’m sharing intent.&lt;/p&gt;

&lt;p&gt;That intent can then be materialized in your environment — with adaptation.&lt;/p&gt;

&lt;p&gt;Same architectural goal. Different context.&lt;/p&gt;

&lt;p&gt;This isn’t blind automation like traditional IaC. It’s careful intent materialization.&lt;/p&gt;

&lt;p&gt;And that difference is subtle — but important.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Future: The Velocity Catalog
&lt;/h3&gt;

&lt;p&gt;What we’ve discussed so far is not just another pattern or a personal experiment. It’s a mental shift we need to make in this AI era.&lt;/p&gt;

&lt;p&gt;snow-utils is simply an example of how this shift took shape for me. The same idea can apply to any tool or script.&lt;/p&gt;

&lt;p&gt;The real opportunity is this: we need to mentor AI to think and act the way we would — embedding our experience, judgment, and operational discipline into it.&lt;/p&gt;

&lt;p&gt;Maybe that’s the next step for us: inject intent into DevOps.&lt;/p&gt;
&lt;h3&gt;
  
  
  Resources
&lt;/h3&gt;

&lt;p&gt;The HIRC demo is just one example. Here is the &lt;strong&gt;4-minute time-lapse&lt;/strong&gt; demo that shows how this pattern works:&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/ZbNjuoCkKeY"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;The same pattern applies across workloads. In the demo repository, I’ve also included the &lt;strong&gt;AI Smart Crowd Counter&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;All you have to say is:&lt;/p&gt;

&lt;p&gt;“Deploy AI Smart Crowd Counter.”&lt;/p&gt;

&lt;p&gt;The underlying primitives remain the same. The intent changes.&lt;/p&gt;

&lt;p&gt;One moment you’re setting up a data catalog. The next, you’re provisioning a Streamlit app and an image-processing pipeline.&lt;/p&gt;

&lt;p&gt;Same intent model. Different outcome.&lt;/p&gt;

&lt;p&gt;That’s the leverage.&lt;/p&gt;

&lt;p&gt;If you’re experimenting with AI agents in your DevOps workflows, start by stabilizing your primitives. Once they’re solid, you can begin layering Skills on top of them.&lt;/p&gt;

&lt;p&gt;And from there, you can build your own Velocity Catalog.&lt;/p&gt;

&lt;p&gt;For reference, the underlying orchestration layer used here is Snowflake Cortex Code:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://docs.snowflake.com/en/user-guide/cortex-code/cortex-code-cli" rel="noopener noreferrer"&gt;Snowflake Cortex Code CLI Documentation&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Visuals note: The conceptual diagrams in this post were generated by Google Gemini.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  About the Author
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Kamesh Sampath&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;is a Lead Developer Advocate at Snowflake, author, and long-time open-source contributor with 25+ years in enterprise software. He works across data engineering and AI with developer communities, helping practitioners turn modern data platforms into systems that hold up in production.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Through talks, writing, and hands-on demos, Kamesh makes cloud, data, and AI topics easier to understand and apply — grounded in real-world constraints. His sessions mix deep technical detail with practical patterns that developers and data teams can apply right away.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Lately, he’s been speaking about Apache NiFi (Snowflake Openflow), AI (Snowflake Cortex), and PostgreSQL.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;He believes technology becomes powerful when it is shared, taught, and built together.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/kameshsampath" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; |&lt;a href="https://linkedin.com/in/kameshsampath" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; |&lt;a href="https://blogs.kameshs.dev/" rel="noopener noreferrer"&gt;Blog&lt;/a&gt; |&lt;a href="https://x.com/kamesh_sampath" rel="noopener noreferrer"&gt; X&lt;/a&gt;&lt;/p&gt;

</description>
      <category>snowflake</category>
      <category>devops</category>
      <category>dataengineering</category>
      <category>ai</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Kamesh Sampath</dc:creator>
      <pubDate>Thu, 27 Feb 2025 18:27:32 +0000</pubDate>
      <link>https://dev.to/kameshsampath/-5ahf</link>
      <guid>https://dev.to/kameshsampath/-5ahf</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/kameshsampath/lets-build-together-a-local-playground-for-apache-polaris-28l5" class="crayons-story__hidden-navigation-link"&gt;Let's Build Together: A Local Playground for Apache&amp;nbsp;Polaris&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/kameshsampath" class="crayons-avatar  crayons-avatar--l  "&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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F871628%2F0eb1f610-f2c7-4371-a6b3-d8c7fcf9123b.jpg" alt="kameshsampath profile" class="crayons-avatar__image" width="394" height="432"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/kameshsampath" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Kamesh Sampath
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Kamesh Sampath
                
              
              &lt;div id="story-author-preview-content-2288941" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/kameshsampath" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F871628%2F0eb1f610-f2c7-4371-a6b3-d8c7fcf9123b.jpg" class="crayons-avatar__image" alt="" width="394" height="432"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Kamesh Sampath&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/kameshsampath/lets-build-together-a-local-playground-for-apache-polaris-28l5" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Feb 25 '25&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/kameshsampath/lets-build-together-a-local-playground-for-apache-polaris-28l5" id="article-link-2288941"&gt;
          Let's Build Together: A Local Playground for Apache&amp;nbsp;Polaris
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/apachepolaris"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;apachepolaris&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/snowflake"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;snowflake&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/kubernetes"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;kubernetes&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/localstack"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;localstack&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
            &lt;a href="https://dev.to/kameshsampath/lets-build-together-a-local-playground-for-apache-polaris-28l5#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            8 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>apachepolaris</category>
      <category>snowflake</category>
      <category>kubernetes</category>
      <category>localstack</category>
    </item>
    <item>
      <title>Let's Build Together: A Local Playground for Apache Polaris</title>
      <dc:creator>Kamesh Sampath</dc:creator>
      <pubDate>Tue, 25 Feb 2025 04:01:17 +0000</pubDate>
      <link>https://dev.to/kameshsampath/lets-build-together-a-local-playground-for-apache-polaris-28l5</link>
      <guid>https://dev.to/kameshsampath/lets-build-together-a-local-playground-for-apache-polaris-28l5</guid>
      <description>&lt;h2&gt;
  
  
  Why I Built a Developer-First Apache Polaris Starter Kit ?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fid6561mm5x9ows0zwinl.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%2Fid6561mm5x9ows0zwinl.png" alt="Photo by Maxime Agnelli on Unsplash" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As builders, we all know the pain of setting up a new development environment. Hours spent configuring dependencies, troubleshooting integration issues, and getting different services to play nicely together. When I started working with &lt;a href="https://github.com/apache/arrow-datafusion-python" rel="noopener noreferrer"&gt;Apache Polaris&lt;/a&gt;, I faced these same challenges – and decided to do something about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge: Getting Started with Apache Polaris
&lt;/h2&gt;

&lt;p&gt;Apache Polaris is a powerful open source Iceberg REST catalog implementation, originally contributed to the Apache Software Foundation by Snowflake. This donation to open source has made enterprise-grade data catalog capabilities accessible to the broader data community via simple REST APIs. &lt;/p&gt;

&lt;p&gt;Setting up Polaris in a development environment can be challenging. You need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A robust container orchestration platform&lt;/li&gt;
&lt;li&gt;A working metastore (typically PostgreSQL)&lt;/li&gt;
&lt;li&gt;S3-compatible storage&lt;/li&gt;
&lt;li&gt;Various security configurations and credentials&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these components requires careful setup and configuration. For builders just getting started or wanting to experiment with Polaris, this overhead can be a significant barrier.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution: A Complete Development Environment
&lt;/h2&gt;

&lt;p&gt;This is why I created &lt;a href="https://github.com/Snowflake-Labs/polaris-local-forge" rel="noopener noreferrer"&gt;an open source starter kit&lt;/a&gt; that provides everything needed to get Polaris up and running in a local development environment. The project follows the true spirit of open source collaboration, building upon and integrating with other excellent open source tools in the ecosystem.&lt;/p&gt;

&lt;p&gt;The kit automates the setup of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A lightweight &lt;a href="https://k3s.io" rel="noopener noreferrer"&gt;k3s&lt;/a&gt; Kubernetes cluster using &lt;a href="https://k3d.io" rel="noopener noreferrer"&gt;k3d&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://localstack.cloud" rel="noopener noreferrer"&gt;LocalStack&lt;/a&gt; for AWS S3 emulation&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.postgresql.org" rel="noopener noreferrer"&gt;PostgreSQL&lt;/a&gt; metastore with proper configurations&lt;/li&gt;
&lt;li&gt;All necessary security credentials and configurations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A key aspect of this starter kit is its comprehensive automation using &lt;a href="https://www.ansible.com" rel="noopener noreferrer"&gt;Ansible&lt;/a&gt;. The &lt;code&gt;polaris-forge-setup&lt;/code&gt; directory houses Ansible playbooks that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automate the entire setup process&lt;/li&gt;
&lt;li&gt;Verify if components are ready for use&lt;/li&gt;
&lt;li&gt;Handle catalog setup and configuration&lt;/li&gt;
&lt;li&gt;Provide cleanup capabilities for development iterations&lt;/li&gt;
&lt;li&gt;Enable smooth transitions to higher environments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This automation-first approach serves two purposes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Immediate Development&lt;/strong&gt;: Developers can get started quickly with minimal manual intervention&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production Readiness&lt;/strong&gt;: The Ansible scripts serve as a template for scaling to higher environments, making it easier to adapt the setup for staging or production use cases&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By keeping everything open source and focusing on community-driven development, we ensure that builders can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Learn from the implementation&lt;/li&gt;
&lt;li&gt;Customize for their specific needs&lt;/li&gt;
&lt;li&gt;Contribute improvements back to the community&lt;/li&gt;
&lt;li&gt;Build upon a foundation of trusted open source tools&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is Snowflake OpenCatalog?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://other-docs.snowflake.com/en/opencatalog/overview" rel="noopener noreferrer"&gt;Snowflake OpenCatalog&lt;/a&gt; is an enterprise-grade implementation and managed service of upstream Polaris, making it incredibly easy to integrate with your existing data stack. By handling the operational complexities of running Polaris at scale, it allows teams to focus on their data applications:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Managed Infrastructure&lt;/strong&gt;: Snowflake handles all operational aspects including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Polaris server management and scaling&lt;/li&gt;
&lt;li&gt;Security and access control&lt;/li&gt;
&lt;li&gt;High availability and reliability&lt;/li&gt;
&lt;li&gt;Regular updates and maintenance&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Enterprise Integration&lt;/strong&gt;: Seamless connectivity with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Snowflake's ecosystem of data services&lt;/li&gt;
&lt;li&gt;Popular query engines and tools&lt;/li&gt;
&lt;li&gt;Existing data governance frameworks&lt;/li&gt;
&lt;li&gt;Enterprise security systems&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Production-Ready Features&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Advanced access controls and auditing&lt;/li&gt;
&lt;li&gt;Cross-region and cross-cloud support&lt;/li&gt;
&lt;li&gt;Enterprise-grade SLAs&lt;/li&gt;
&lt;li&gt;Professional support&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  From Local Development to Enterprise Scale
&lt;/h3&gt;

&lt;p&gt;This starter kit provides an ideal path for builders working with Apache Polaris and considering OpenCatalog for production deployment. By working with the upstream version in this development environment, you:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Gain hands-on experience with core concepts&lt;/li&gt;
&lt;li&gt;Understand the underlying architecture&lt;/li&gt;
&lt;li&gt;Can prototype and test implementations&lt;/li&gt;
&lt;li&gt;Build expertise that transfers to OpenCatalog&lt;/li&gt;
&lt;li&gt;Have a clear path to production scaling&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When you're ready to move to production, the concepts and patterns you've learned here will help you make the most of OpenCatalog's enterprise capabilities while Snowflake handles the operational complexity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Design Decisions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why Kubernetes with k3s and k3d?
&lt;/h3&gt;

&lt;p&gt;While Docker Compose is often the go-to choice for local development environments, Apache Polaris's distributed nature benefits significantly from Kubernetes's capabilities. Here's why:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Advanced Networking&lt;/strong&gt;: Kubernetes provides sophisticated networking between components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatic service discovery and DNS resolution&lt;/li&gt;
&lt;li&gt;Internal load balancing for scalable services&lt;/li&gt;
&lt;li&gt;Ingress management for external access&lt;/li&gt;
&lt;li&gt;Network policies for traffic control&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Declarative Configuration&lt;/strong&gt;: Using tools like Helm and Kustomize, we can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Maintain separate configurations for different environments&lt;/li&gt;
&lt;li&gt;Version control our infrastructure setup&lt;/li&gt;
&lt;li&gt;Apply consistent changes across deployments&lt;/li&gt;
&lt;li&gt;Manage complex dependencies between services&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Reliable State Management&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;StatefulSets for databases and stateful services&lt;/li&gt;
&lt;li&gt;PersistentVolumes for durable storage&lt;/li&gt;
&lt;li&gt;Backup and restore capabilities&lt;/li&gt;
&lt;li&gt;Data replication when needed&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Security and Configuration&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Native secrets management&lt;/li&gt;
&lt;li&gt;Role-Based Access Control (RBAC)&lt;/li&gt;
&lt;li&gt;ConfigMaps for configuration management&lt;/li&gt;
&lt;li&gt;Service accounts for component authentication&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Production Readiness&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Same tools and patterns used in production&lt;/li&gt;
&lt;li&gt;Easy scaling of components&lt;/li&gt;
&lt;li&gt;Built-in monitoring and logging&lt;/li&gt;
&lt;li&gt;Consistent behavior across environments&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I specifically chose k3s because it's lightweight and perfect for development environments. Using k3d allows us to run k3s in Docker containers, making it even more convenient for local development. It provides a full Kubernetes experience without the resource overhead of something like minikube.&lt;/p&gt;

&lt;h3&gt;
  
  
  LocalStack for S3 Integration
&lt;/h3&gt;

&lt;p&gt;While we could have required developers to use actual AWS S3, LocalStack provides a perfect local alternative. It emulates AWS services locally, which means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No cloud costs during development&lt;/li&gt;
&lt;li&gt;No need for AWS credentials&lt;/li&gt;
&lt;li&gt;Faster development cycles&lt;/li&gt;
&lt;li&gt;Ability to work offline&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  PostgreSQL as the Metastore
&lt;/h3&gt;

&lt;p&gt;PostgreSQL was a natural choice for the metastore. It's:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Well-documented and widely used&lt;/li&gt;
&lt;li&gt;Easy to containerize&lt;/li&gt;
&lt;li&gt;Highly reliable&lt;/li&gt;
&lt;li&gt;Supported out of the box by Polaris&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Kustomize for Deployment Management
&lt;/h3&gt;

&lt;p&gt;Kustomize allows us to manage Kubernetes manifests in a clean, declarative way. It makes it easy to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Maintain different configurations for different environments&lt;/li&gt;
&lt;li&gt;Override settings without modifying base configurations&lt;/li&gt;
&lt;li&gt;Keep configurations DRY and maintainable&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Let me walk you through how to get up and running with this starter kit. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensure you have the prerequisites installed:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Required tools and their version checks:&lt;/span&gt;

&lt;span class="c"&gt;# Docker (Desktop or Engine)&lt;/span&gt;
docker &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;span class="c"&gt;# Example output: Docker version 24.0.7&lt;/span&gt;

&lt;span class="c"&gt;# Kubernetes CLI&lt;/span&gt;
kubectl version &lt;span class="nt"&gt;--client&lt;/span&gt;
&lt;span class="c"&gt;# Example output: Client Version: v1.28.2&lt;/span&gt;

&lt;span class="c"&gt;# k3d (&amp;gt;= 5.0.0)&lt;/span&gt;
k3d version
&lt;span class="c"&gt;# Example output: k3d version v5.6.0&lt;/span&gt;

&lt;span class="c"&gt;# Python (&amp;gt;= 3.11)&lt;/span&gt;
python &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;span class="c"&gt;# Example output: Python 3.12.1&lt;/span&gt;

&lt;span class="c"&gt;# uv (Python packaging tool)&lt;/span&gt;
uv &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;span class="c"&gt;# Example output: uv 0.1.12&lt;/span&gt;

&lt;span class="c"&gt;# Task&lt;/span&gt;
task &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;span class="c"&gt;# Example output: Task version: v3.34.1&lt;/span&gt;

&lt;span class="c"&gt;# LocalStack (&amp;gt;= 3.0.0)&lt;/span&gt;
localstack &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;span class="c"&gt;# Example output: 3.0.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Sign-up for &lt;a href="https://app.localstack.cloud/sign-up" rel="noopener noreferrer"&gt;Localstack&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Initial Setup
&lt;/h3&gt;

&lt;p&gt;Clone the repository and set up your environment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/snowflake-labs/polaris-local-forge
&lt;span class="nb"&gt;cd &lt;/span&gt;polaris-local-forge

&lt;span class="c"&gt;# Set up environment variables&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PROJECT_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PWD&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;KUBECONFIG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PWD&lt;/span&gt;&lt;span class="s2"&gt;/.kube/config"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;K3D_CLUSTER_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;polaris-local-forge
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;K3S_VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;v1.32.1-k3s1
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;FEATURES_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PWD&lt;/span&gt;&lt;span class="s2"&gt;/k8s"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Python Environment Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install uv&lt;/span&gt;
pip &lt;span class="nb"&gt;install &lt;/span&gt;uv

&lt;span class="c"&gt;# Set up Python environment&lt;/span&gt;
uv python pin 3.12
uv venv
&lt;span class="nb"&gt;source&lt;/span&gt; .venv/bin/activate  &lt;span class="c"&gt;# On Unix-like systems&lt;/span&gt;
uv &lt;span class="nb"&gt;sync&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Deploy the Environment
&lt;/h3&gt;

&lt;p&gt;The setup process is automated through several scripts:&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;# Generate required sensitive files&lt;/span&gt;
&lt;span class="nv"&gt;$PROJECT_HOME&lt;/span&gt;/polaris-forge-setup/prepare.yml

&lt;span class="c"&gt;# Create and set up the cluster&lt;/span&gt;
&lt;span class="nv"&gt;$PROJECT_HOME&lt;/span&gt;/bin/setup.sh

&lt;span class="c"&gt;# Wait for deployments to be ready&lt;/span&gt;
&lt;span class="nv"&gt;$PROJECT_HOME&lt;/span&gt;/polaris-forge-setup/cluster_checks.yml &lt;span class="nt"&gt;--tags&lt;/span&gt; namespace,postgresql,localstack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Deploy Polaris
&lt;/h3&gt;

&lt;p&gt;This is where things get interesting - deploying Polaris itself. You have two options for the container images:&lt;/p&gt;

&lt;h4&gt;
  
  
  Option 1: Use Pre-built Images
&lt;/h4&gt;

&lt;p&gt;Apache Polaris doesn't currently publish official images, but you can use our pre-built images with PostgreSQL dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker pull ghcr.io/snowflake-labs/polaris-local-forge/apache-polaris-server-pgsql
docker pull ghcr.io/snowflake-labs/polaris-local-forge/apache-polaris-admin-tool-pgsql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Option 2: Build Images Locally
&lt;/h4&gt;

&lt;p&gt;Alternatively, you can build the images from source:&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;# Update IMAGE_REGISTRY in Taskfile.yml, then run:&lt;/span&gt;
task images
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you choose to build locally, remember to update the image references in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;k8s/polaris/deployment.yaml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;k8s/polaris/bootstrap.yaml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;k8s/polaris/purge.yaml&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Deploy and Verify
&lt;/h4&gt;

&lt;p&gt;Apply the Kubernetes manifests:&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;# Apply Polaris manifests&lt;/span&gt;
kubectl apply &lt;span class="nt"&gt;-k&lt;/span&gt; &lt;span class="nv"&gt;$PROJECT_HOME&lt;/span&gt;/k8s/polaris

&lt;span class="c"&gt;# Verify deployments and jobs&lt;/span&gt;
&lt;span class="nv"&gt;$PROJECT_HOME&lt;/span&gt;/polaris-forge-setup/cluster_checks.yml &lt;span class="nt"&gt;--tags&lt;/span&gt; polaris
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Setting Up Your First Catalog
&lt;/h3&gt;

&lt;p&gt;Before creating your first catalog, configure your AWS environment variables:&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;export &lt;/span&gt;&lt;span class="nv"&gt;AWS_ENDPOINT_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://localstack.localstack:14566
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;AWS_ACCESS_KEY_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;test
export &lt;/span&gt;&lt;span class="nv"&gt;AWS_SECRET_ACCESS_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;test
export &lt;/span&gt;&lt;span class="nv"&gt;AWS_REGION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;us-east-1

&lt;span class="c"&gt;# Run the catalog setup&lt;/span&gt;
&lt;span class="nv"&gt;$PROJECT_HOME&lt;/span&gt;/polaris-forge-setup/catalog_setup.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Pro Tip&lt;/strong&gt;: You can customize the default catalog settings by modifying values in &lt;a href="https://github.com/Snowflake-Labs/polaris-local-forge/blob/main/polaris-forge-setup/defaults/main.yml" rel="noopener noreferrer"&gt;polaris-forge-setup/defaults/main.yml&lt;/a&gt;. This file contains configurable parameters for your catalog, principal roles, and permissions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Play with the Catalog
&lt;/h3&gt;

&lt;p&gt;Once your catalog is set up, you can explore its functionality using the provided Jupyter notebook. The notebook &lt;a href="https://github.com/Snowflake-Labs/polaris-local-forge/blob/main/notebooks/verify_setup.ipynb" rel="noopener noreferrer"&gt;notebooks/verify_setup.ipynb&lt;/a&gt; walks you through:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating a namespace&lt;/li&gt;
&lt;li&gt;Defining a table&lt;/li&gt;
&lt;li&gt;Inserting sample data&lt;/li&gt;
&lt;li&gt;Verifying data storage in LocalStack&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This hands-on exploration helps you understand how Polaris integrates with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The PostgreSQL metastore for catalog management&lt;/li&gt;
&lt;li&gt;LocalStack's S3 emulation for data storage&lt;/li&gt;
&lt;li&gt;The overall Apache Iceberg table format structure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can visually verify your setup by checking the LocalStack console at &lt;a href="https://app.localstack.cloud/inst/default/resources/s3/polardb" rel="noopener noreferrer"&gt;https://app.localstack.cloud/inst/default/resources/s3/polardb&lt;/a&gt;, where you'll see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Catalog storage structure&lt;/li&gt;
&lt;li&gt;Metadata files&lt;/li&gt;
&lt;li&gt;Actual data files&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Video Walkthrough
&lt;/h3&gt;

&lt;p&gt;For a detailed visual guide of setting up and using this development environment, check out my walkthrough video:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/LvIUv3JtUNs" rel="noopener noreferrer"&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%2Ftsbcvh52bj6fszg39r0n.jpg" alt="Apache Polaris Local Development Setup" width="480" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This video demonstrates the entire process from initial setup to running your first queries.&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshooting Tips
&lt;/h2&gt;

&lt;p&gt;If you run into issues, here are some helpful commands for debugging:&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;# Check Polaris server logs&lt;/span&gt;
kubectl logs &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; polaris deployment/polaris

&lt;span class="c"&gt;# Check PostgreSQL logs&lt;/span&gt;
kubectl logs &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; polaris statefulset/postgresql

&lt;span class="c"&gt;# Check LocalStack logs&lt;/span&gt;
kubectl logs &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; localstack deployment/localstack

&lt;span class="c"&gt;# Check events in the polaris namespace&lt;/span&gt;
kubectl get events &lt;span class="nt"&gt;-n&lt;/span&gt; polaris &lt;span class="nt"&gt;--sort-by&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'.lastTimestamp'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Impact: Streamlined Development Experience
&lt;/h2&gt;

&lt;p&gt;With this starter kit, what used to take days of setup and configuration now takes minutes. Builders can focus on creating and experimenting with Polaris rather than wrestling with infrastructure setup.&lt;/p&gt;

&lt;p&gt;The kit is open source and available on &lt;a href="https://github.com/Snowflake-Labs/polaris-local-forge" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. I welcome contributions and feedback from the community. Together, we can make the development experience even better for everyone working with Apache Polaris.&lt;/p&gt;

&lt;p&gt;Building should be about creating, not configuring. This starter kit aims to remove the friction from getting started with Apache Polaris, allowing builders to focus on what matters most – creating great applications.&lt;/p&gt;

&lt;p&gt;Dont forget to check another project where I used this starter kit &lt;a href="https://github.com/kameshsampath/balloon-popper-demo" rel="noopener noreferrer"&gt;https://github.com/kameshsampath/balloon-popper-demo&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Related Projects and Tools
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Core Components
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/apache/arrow-datafusion-python" rel="noopener noreferrer"&gt;Apache Polaris&lt;/a&gt; - Data Catalog and Governance Platform&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://py.iceberg.apache.org/" rel="noopener noreferrer"&gt;PyIceberg&lt;/a&gt; - Python library for Apache Iceberg&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/localstack/localstack" rel="noopener noreferrer"&gt;LocalStack&lt;/a&gt; - AWS Cloud Service Emulator&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://k3d.io" rel="noopener noreferrer"&gt;k3d&lt;/a&gt; - k3s in Docker&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://k3s.io" rel="noopener noreferrer"&gt;k3s&lt;/a&gt; - Lightweight Kubernetes Distribution&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.ansible.com" rel="noopener noreferrer"&gt;Ansible&lt;/a&gt; - Automation Platform&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Development Tools
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.docker.com/" rel="noopener noreferrer"&gt;Docker&lt;/a&gt; - Container Platform&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://kubernetes.io/" rel="noopener noreferrer"&gt;Kubernetes&lt;/a&gt; - Container Orchestration&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://helm.sh/" rel="noopener noreferrer"&gt;Helm&lt;/a&gt; - Kubernetes Package Manager&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://kubernetes.io/docs/reference/kubectl/" rel="noopener noreferrer"&gt;kubectl&lt;/a&gt; - Kubernetes CLI&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/astral-sh/uv" rel="noopener noreferrer"&gt;uv&lt;/a&gt; - Python Packaging Tool&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>apachepolaris</category>
      <category>snowflake</category>
      <category>kubernetes</category>
      <category>localstack</category>
    </item>
    <item>
      <title>Elements of Event Driven Architecture(EDA)</title>
      <dc:creator>Kamesh Sampath</dc:creator>
      <pubDate>Wed, 08 Nov 2023 08:06:04 +0000</pubDate>
      <link>https://dev.to/kameshsampath/elements-of-event-driven-architectureeda-4jnf</link>
      <guid>https://dev.to/kameshsampath/elements-of-event-driven-architectureeda-4jnf</guid>
      <description>&lt;p&gt;Well, we encounter lots of data in our everyday life e.g. weather reports, flight timings, food deliveries etc., All these data are continuous and flowing from variety of sources. Such continuously flowing data is called a &lt;strong&gt;Data Stream&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpu1f3s6d26psc7d26ue4.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%2Fpu1f3s6d26psc7d26ue4.png" alt="Data Stream" width="278" height="228"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A raw data(stream) is useless for any application unless it has some identifiable element to it.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Let me explain it with few examples, &lt;em&gt;Joe joined Acme crop as a Developer on 25 October 2023&lt;/em&gt;, &lt;em&gt;Mini placed an order for two pizzas at 12:00 PM&lt;/em&gt;. In these data examples if we take out the verbs(actions) "joined" and "ordered" along with the time "25 Oct" and "12:00 PM"&amp;nbsp;, the whole data become useless.&lt;br&gt;
&amp;nbsp;&lt;br&gt;
For an application to effectively use the data stream, the data in the stream should be an &lt;strong&gt;event&lt;/strong&gt;, a data that has &lt;strong&gt;time&lt;/strong&gt; and &lt;strong&gt;action&lt;/strong&gt; associated with it. A stream of data as events brings a great value to applications via analytics, triggers, chaining etc.,&amp;nbsp;&lt;/p&gt;

&lt;p&gt;With &lt;em&gt;Mini placed an order for two pizzas at 12:00 PM event&lt;/em&gt;, we could extract the following analytical information,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is Mini placing order for two pizzas everyday?&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Is the order placed at 12:00PM everyday?&lt;/li&gt;
&lt;li&gt;Is the order is delivered by the same food chain?&lt;/li&gt;
&lt;li&gt;What pizzas were ordered?&lt;/li&gt;
&lt;li&gt;Are food chains delivering the orders on time&amp;nbsp;?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The process of using the events and building such analytical information is called &lt;strong&gt;Data Processing&lt;/strong&gt;. Data Processing could be done by a human, an application, an IoT device etc.,&lt;/p&gt;

&lt;p&gt;With any data streaming scenario there is always two essential primitive entities,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Event Producer&lt;/strong&gt; is someone or something that produces an event in our example above Mini is event producer who places the order for pizza.&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%2Fl0xbfsevupoo05wxpy42.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%2Fl0xbfsevupoo05wxpy42.png" alt="Event Producer" width="630" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Event Consumer&lt;/strong&gt; is again someone or something that consumes or uses the event produced by the Event Producer. Taking the same Mini's order example there could be Pizza house that takes, processes and delivers the order.&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%2Fcq1eqm1g80iir5spkls3.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%2Fcq1eqm1g80iir5spkls3.png" alt="Event Consumer" width="524" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we understood the Event Producers produces events that are being consumed by Event Consumers, software architectures started to evolve around building applications that act as an Event Producer/Consumer and leverage these streams of events. An architectural style of building  applications around events is called an &lt;strong&gt;Event Driven Architecture(EDA)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fws0av94lexm19rlarpoq.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%2Fws0av94lexm19rlarpoq.png" alt="Event Driven Architecture" width="800" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When building applications using EDA, enforces few basic requirements on the Platform and a software Framework that will be used to build such applications.&amp;nbsp;&lt;/p&gt;

&lt;p&gt;The platform that will be used to build the such applications need to be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scalable&lt;/strong&gt; - as events are continuously flowing there could be sudden spikes to number of events that might come in, the platform need to be scalable or elastic to handle such spikes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Durable&lt;/strong&gt; - as events can be consumed immediately or bit late in time, the platform should support a mechanism of delivering events durably at time of need&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resilient&lt;/strong&gt; - The platform should be capable of handling failures and recovering from them without data loss&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Retention&lt;/strong&gt; - Retaining of data until a configurable amount time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Responding to Events&lt;/strong&gt; - The platform should also be able to respond to events at bare minimum acknowledge the event on receive&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ordering&lt;/strong&gt; - As events are associated with time, ordering of the events helps consumers who need to process them in specific order e.g within a time range or date range etc.,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A sole platform alone might not be enough to build an effective EDA styled application. There is greater need for an integration into the platform via plugins, API etc., In other words, a framework that is extensible and pluggable, and works on common semantics. &lt;/p&gt;

&lt;p&gt;The framework should support:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Data Sources&lt;/strong&gt; - the sources from where the events are generated i.e. Event Producers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Sinks&lt;/strong&gt; - the destinations where the processed event is drained into i.e. Event Consumers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API&lt;/strong&gt; - An interface to connect and work with the platform, data sources and data sinks.&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%2Fpkcphngtg3ism9a097er.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%2Fpkcphngtg3ism9a097er.png" alt="Platform and Integration" width="799" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Some great of Data Streaming platforms,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://kafka.apache.org" rel="noopener noreferrer"&gt;Apache Kafka&lt;/a&gt; - Developed at LinkedIn and Opensources to Apache Software Foundation&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://redpanda.com" rel="noopener noreferrer"&gt;Redpanda&lt;/a&gt; - is a simple, powerful, and cost-efficient streaming data platform that is compatible with Kafka® APIs while eliminating Kafka complexity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Apache Kafka also supports processing of streaming data using its ecosystem of &lt;a href="https://kafka.apache.org/documentation/streams/" rel="noopener noreferrer"&gt;Streaming API&lt;/a&gt; and &lt;a href="https://ksqldb.io/" rel="noopener noreferrer"&gt;ksqlDB&lt;/a&gt;. But for an effective architecture, it is always nice to have the core data streaming and data processing to be decoupled(&lt;a href="https://en.wikipedia.org/wiki/Separation_of_concerns" rel="noopener noreferrer"&gt;Separation of Concerns&lt;/a&gt;). Such decoupling helps in processing data from heterogeneous sources e.g. Apache Kafka, Database, File System CSV files etc.,&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://flink.apache.org" rel="noopener noreferrer"&gt;Apache Flink&lt;/a&gt; is one such framework and distributed processing engine for stateful computations over unbounded(Apache Kafka) and bounded data streams(Database).&lt;/p&gt;

&lt;p&gt;Just to summarise we learnt,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is a Data Stream and an Event&lt;/li&gt;
&lt;li&gt;What is a Data Producer and Data Consumer&lt;/li&gt;
&lt;li&gt;An architecture style that is used to build application around Events&lt;/li&gt;
&lt;li&gt;An effective EDA platform&lt;/li&gt;
&lt;li&gt;Some great platform and frameworks that could be used to build EDA applications.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>datastreaming</category>
      <category>kafka</category>
      <category>dataprocessing</category>
      <category>basics</category>
    </item>
    <item>
      <title>Trigger CI using Terraform Cloud</title>
      <dc:creator>Kamesh Sampath</dc:creator>
      <pubDate>Mon, 10 Apr 2023 01:23:33 +0000</pubDate>
      <link>https://dev.to/kameshsampath/trigger-ci-using-terraform-cloud-1mao</link>
      <guid>https://dev.to/kameshsampath/trigger-ci-using-terraform-cloud-1mao</guid>
      <description>&lt;p&gt;Continuous Integration(CI) pipelines needs a &lt;strong&gt;target&lt;/strong&gt; infrastructure to which the CI artifacts are deployed. The deployments are handled by CI or we can leverage Continuous Deployment pipelines. Modern day architecture uses automation tools like &lt;a href="https://terraform.io" rel="noopener noreferrer"&gt;terraform&lt;/a&gt;, &lt;a href="https://www.ansible.com/" rel="noopener noreferrer"&gt;ansible&lt;/a&gt; to provision the target infrastructure, this type of provisioning is called &lt;a href="https://en.wikipedia.org/wiki/Infrastructure_as_code" rel="noopener noreferrer"&gt;IaC&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Usually CI/CD and IaC don't run in tandem. Many times we want to trigger the CI pipeline only when the &lt;strong&gt;target&lt;/strong&gt; infrastructure is ready to bootstrap with software components that are required by CI/CD pipelines.&lt;/p&gt;

&lt;p&gt;As part of this DIY blog let us tackle the aforementioned problem with an use case. &lt;/p&gt;

&lt;h2&gt;
  
  
  Use Case
&lt;/h2&gt;

&lt;p&gt;As CI/CD user I would like to provision a Kubernetes Cluster on Google Cloud Platform(GKE) using Terraform. The successful provision of the cluster should &lt;strong&gt;notify&lt;/strong&gt; a CI pipeline to start bootstrapping &lt;a href="https://argo-cd.readthedocs.io/en/stable/" rel="noopener noreferrer"&gt;ArgoCD&lt;/a&gt; on to GKE.&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%2Fa56swhyp5lzm9n5d9kpr.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%2Fa56swhyp5lzm9n5d9kpr.png" alt="Architecture Overview" width="799" height="491"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What you need ?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;a href="https://app.terraform.io/public/signup/account" rel="noopener noreferrer"&gt;Terraform Cloud Account&lt;/a&gt;. Create a workspace on the terraform cloud to be used for this exercise.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://cloud.google.com" rel="noopener noreferrer"&gt;Google Cloud Account&lt;/a&gt; used to create the Google Kubernetes Engine(GKE) cluster.&lt;/li&gt;
&lt;li&gt;Though we can use any CI platform, for this demo we will use &lt;a href="https://www.harness.io/products/continuous-integration" rel="noopener noreferrer"&gt;Harness CI&lt;/a&gt;as our CI platform. You can do a &lt;strong&gt;free tier&lt;/strong&gt; signup from &lt;a href="https://app.harness.io/auth/#/signup/?module=ci&amp;amp;utm_source=internal&amp;amp;utm_medium=social&amp;amp;utm_campaign=community&amp;amp;utm_content=kamesh-tfc-ci-demos&amp;amp;utm_term=tutorial" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Demo Sources
&lt;/h2&gt;

&lt;p&gt;The demo uses the following git repositories a sources,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;IaC &lt;a href="https://github.com/harness-apps/vanilla-gke" rel="noopener noreferrer"&gt;vanilla-gke&lt;/a&gt;: the terraform source repository that will be used with terraform cloud to provision GKE.&lt;/li&gt;
&lt;li&gt;Kubernetes manifests &lt;a href="https://github.com/harness-apps/bootstrap-gke" rel="noopener noreferrer"&gt;bootstrap-argocd&lt;/a&gt;: the repository that holds kubernetes manifests to bootstrap argo CD on to the GKE cluster&lt;/li&gt;
&lt;li&gt;Harness CI Pipeline &lt;a href="https://github.com/harness-apps/tfc-notification-demo" rel="noopener noreferrer"&gt;tfc-notification-demo&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Fork and Clone the Sources
&lt;/h3&gt;

&lt;p&gt;To make fork and clone easier we will use &lt;a href="https://cli.github.com/" rel="noopener noreferrer"&gt;gh CLI&lt;/a&gt;. Download the add &lt;code&gt;gh&lt;/code&gt; to your &lt;code&gt;$PATH&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let us create a directory where we want to place all our demo sources,&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;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/tfc-notification-demo"&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/tfc-notification-demo"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;DEMO_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PWD&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  IaC
&lt;/h4&gt;

&lt;p&gt;Clone and fork &lt;code&gt;vanilla-gke&lt;/code&gt; repo,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh repo clone harness-apps/vanilla-gke
&lt;span class="nb"&gt;cd &lt;/span&gt;vanilla-gke
gh repo fork
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;TFC_GKE_REPO&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PWD&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Bootstrap Argo CD Sources
&lt;/h4&gt;

&lt;p&gt;Clone and fork &lt;code&gt;bootstrap-argocd&lt;/code&gt; repo,&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;cd&lt;/span&gt; ..
gh repo clone harness-apps/bootstrap-argocd
&lt;span class="nb"&gt;cd &lt;/span&gt;bootstrap-argocd
gh repo fork
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;ARGOCD_BOOTSTRAP_REPO&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PWD&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Harness CI Pipeline
&lt;/h4&gt;

&lt;p&gt;Clone and fork &lt;code&gt;tfc-notification-demo&lt;/code&gt; repo,&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;cd&lt;/span&gt; ..
gh repo clone harness-apps/tfc-notification-demo
&lt;span class="nb"&gt;cd &lt;/span&gt;tfc-notification-demo
gh repo fork
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;TFC_DEMO_REPO&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PWD&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For rest of the blog we will reference the repositories &lt;code&gt;vanilla-gke&lt;/code&gt; and &lt;code&gt;bootstrap-argocd&lt;/code&gt; and &lt;code&gt;tfc-notification-demo&lt;/code&gt; as &lt;code&gt;$TFC_GKE_REPO&lt;/code&gt;, &lt;code&gt;$ARGOCD_BOOTSTRAP_REPO&lt;/code&gt; and &lt;code&gt;$TFC_DEMO_REPO&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Harness CI
&lt;/h2&gt;

&lt;p&gt;In the following sections we will define and create the resources required to define a CI pipeline using Harness platform.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create Harness Project
&lt;/h3&gt;

&lt;p&gt;Create new harness project named &lt;code&gt;terraform_integration_demos&lt;/code&gt; using Harness Web Console,&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%2Fx2xlbd9079oesmni06ut.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%2Fx2xlbd9079oesmni06ut.png" alt="New Harness Project" width="800" height="1302"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Update its details as shown,&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%2F6hw2w4j51yosjj3in819.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%2F6hw2w4j51yosjj3in819.png" alt="New Harness Project Details" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Follow the wizard leaving rest to defaults and on the last screen choose &lt;strong&gt;Continuous Integration&lt;/strong&gt;,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj2emzksrd7wplaapqjlj.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%2Fj2emzksrd7wplaapqjlj.png" alt="Use CI" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Go to Module&lt;/strong&gt; to go to project home page.&lt;/p&gt;

&lt;h3&gt;
  
  
  Define New Pipeline
&lt;/h3&gt;

&lt;p&gt;Click &lt;strong&gt;Pipelines&lt;/strong&gt; to define a new pipeline,&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%2Fkgads8qcwj6t8y7oeg4m.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%2Fkgads8qcwj6t8y7oeg4m.png" alt="Get Started with CI" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For this demo will be doing manual clone, hence disable the clone,&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%2Faf9r24aycvqp0noecy2o.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%2Faf9r24aycvqp0noecy2o.png" alt="Disable" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on &lt;strong&gt;Pipelines&lt;/strong&gt; and delete the default &lt;strong&gt;Build pipeline&lt;/strong&gt;,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftdmpydgk99elqufic570.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%2Ftdmpydgk99elqufic570.png" alt="Delete Pipeline" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Add &lt;code&gt;harnessImage&lt;/code&gt; Docker Registry Connector
&lt;/h3&gt;

&lt;p&gt;As part of pipelines we will be pulling image from DockerHub. &lt;code&gt;harnesImage&lt;/code&gt; &lt;a&gt;Docker Registry Connector&lt;/a&gt; helps pulling the public Docker Hub images as an anonymous user.&lt;/p&gt;

&lt;p&gt;Let us configure an &lt;code&gt;harnesImage&lt;/code&gt; connector as described in docker registry connectors. The pipelines we create as part of the later section will use this connector.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configure GitHub
&lt;/h3&gt;

&lt;h4&gt;
  
  
  GitHub Credentials
&lt;/h4&gt;

&lt;p&gt;Create a &lt;a href="https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token" rel="noopener noreferrer"&gt;GitHub PAT&lt;/a&gt; for the account where you have have forked the repositories &lt;code&gt;$TFC_GKE_REPO&lt;/code&gt; and &lt;code&gt;$ARGOCD_BOOTSTRAP_REPO&lt;/code&gt;. We will refer to the token as &lt;code&gt;$GITHUB_PAT&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;From the &lt;strong&gt;Project Setup&lt;/strong&gt; click &lt;strong&gt;Secrets&lt;/strong&gt;,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd21zbiyr2gdqjt4j0wrl.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%2Fd21zbiyr2gdqjt4j0wrl.png" alt="New Text Secret" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Update the encrypted text secret details as shown,&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%2F7bijo1z8gv5s99txxceq.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%2F7bijo1z8gv5s99txxceq.png" alt="GitHub PAT Secret" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Save&lt;/strong&gt; to save the secret,&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%2Fqb5cu0a0bg5fk51w1o7z.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%2Fqb5cu0a0bg5fk51w1o7z.png" alt="Project Secrets" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Connector
&lt;/h4&gt;

&lt;p&gt;As we need to clone the sources from GitHub, we need to define a &lt;strong&gt;GitHub Connector&lt;/strong&gt;,  from the &lt;strong&gt;Project Setup&lt;/strong&gt; click &lt;strong&gt;Connectors&lt;/strong&gt;,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgra2qdl6a7x66btz5jqk.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%2Fgra2qdl6a7x66btz5jqk.png" alt="New Connector" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From connector list select &lt;strong&gt;GitHub&lt;/strong&gt;,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fktjszxdgilu44rn36my0.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%2Fktjszxdgilu44rn36my0.png" alt="New GitHub Connector" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enter the name as &lt;strong&gt;GitHub&lt;/strong&gt;,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcdlxl7h6wm4aa724bi8l.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%2Fcdlxl7h6wm4aa724bi8l.png" alt="GitHub Connector Overview" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Continue&lt;/strong&gt; to enter the connector details,&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%2Fx13z7pzaslkj14uznd6g.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%2Fx13z7pzaslkj14uznd6g.png" alt="GitHub Connector Details" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Continue&lt;/strong&gt; and update the GitHub Connector credentials,&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%2Fnx9y4cezd1899j4dl1qm.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%2Fnx9y4cezd1899j4dl1qm.png" alt="GitHub Connector Credentials" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When selecting the &lt;strong&gt;Personal Access Token&lt;/strong&gt; make sure you select the &lt;code&gt;GitHub PAT&lt;/code&gt; that we defined in previous section,&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%2Fiyf7wqipnwk9dx7zafpy.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%2Fiyf7wqipnwk9dx7zafpy.png" alt="GitHub PAT Secret" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Continue&lt;/strong&gt; and use select &lt;strong&gt;Connect through Harness Platform&lt;/strong&gt;,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo99912vww36fbleygp9d.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%2Fo99912vww36fbleygp9d.png" alt="Connect through Harness Platform" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Save and Continue&lt;/strong&gt; to run the connection test, if all went well the connection should successful,&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%2F2090ay6wtd98l1yb78kz.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%2F2090ay6wtd98l1yb78kz.png" alt="GH Connection Success" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Google Cloud Service Account Secret
&lt;/h2&gt;

&lt;p&gt;We need Google Service Account(GSA) credentials(JSON Key) to query the GKE cluster details and create resources on it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Set environment
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;GCP_PROJECT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"the Google Cloud Project where Kubernetes Cluster is created"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;GSA_KEY_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"path where to store the key file"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create SA
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud iam service-accounts create gke-user &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--description&lt;/span&gt; &lt;span class="s2"&gt;"GKE User"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--display-name&lt;/span&gt; &lt;span class="s2"&gt;"gke-user"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  IAM Binding
&lt;/h3&gt;

&lt;p&gt;Add permissions to the user to be able to provision kubernetes resources,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud projects add-iam-policy-binding &lt;span class="nv"&gt;$GCP_PROJECT&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--member&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"serviceAccount:&lt;/span&gt;&lt;span class="nv"&gt;$GSA_NAME&lt;/span&gt;&lt;span class="s2"&gt;@&lt;/span&gt;&lt;span class="nv"&gt;$GCP_PROJECT&lt;/span&gt;&lt;span class="s2"&gt;.iam.gserviceaccount.com"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--role&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"roles/container.admin"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Download And Save GSA Key
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;IMPORTANT: Only security admins can create the JSON keys. Ensure the Google Cloud user you are using has &lt;strong&gt;Security Admin&lt;/strong&gt; role.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud iam service-accounts keys create &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GSA_KEY_FILE&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--iam-account&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"gke-user@&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;GCP_PROJECT&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.iam.gserviceaccount.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  GSA Secret
&lt;/h3&gt;

&lt;p&gt;Get back to the &lt;strong&gt;Project Setup&lt;/strong&gt; click &lt;strong&gt;Secrets&lt;/strong&gt;,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2jbw4oldn0x2729ypy9g.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%2F2jbw4oldn0x2729ypy9g.png" alt="New File Secret" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add the GSA secret details as shown,&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%2Fecn7fe4taun68wbzhhn2.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%2Fecn7fe4taun68wbzhhn2.png" alt="GSA Secret Details" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;IMPORTANT&lt;/strong&gt;: When you browse and select make sure you select the &lt;code&gt;$GSA_KEY_FILE&lt;/code&gt; as the file for the secret.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Click &lt;strong&gt;Save&lt;/strong&gt; to save the secret,&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%2Fy69kufxvkhg8ia8qxs0q.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%2Fy69kufxvkhg8ia8qxs0q.png" alt="Project Secrets" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Terraform Workspace
&lt;/h2&gt;

&lt;p&gt;On your terraform cloud account create a new workspace called &lt;strong&gt;vanilla-gke&lt;/strong&gt;. Update the workspace settings to use Version Control and make it point to $TFC_GKE_REPO.&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%2Ftuifarjnq1vxpf1h9dhd.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%2Ftuifarjnq1vxpf1h9dhd.png" alt="TFC Workspace VCS" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Configure the workspace with following variables,&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%2Fsxld08inhuftsu4r87l1.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%2Fsxld08inhuftsu4r87l1.png" alt="TFC Workspace Variables" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For more details on available variables, check &lt;a href="https://github.com/harness-apps/vanilla-gke#inputs" rel="noopener noreferrer"&gt;Terraform Inputs&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;IMPORTANT&lt;/strong&gt;: The &lt;code&gt;GOOGLE_CREDENTIALS&lt;/code&gt; is Google Service Account JSON Key with permissions to create GKE cluster. Please check the &lt;a href="https://github.com/harness-apps/vanilla-gke#pre-requisites" rel="noopener noreferrer"&gt;https://github.com/harness-apps/vanilla-gke#pre-requisites&lt;/a&gt; for the required roles and permissions. This key will be used by Terraform to create the GKE cluster. When you add the key to terraform variables, you need to make it as base64 encoded e.g. &lt;code&gt;cat YOUR_GOOGLE_CREDENTIALS_KEY_FILE | tr -d \\n&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Going forward we will refer to the Terraform Workspace as &lt;code&gt;$TF_WORKSPACE&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Lookup your terraform cloud organizations&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%2Fd9txo4xjf5wukxi9pfp3.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%2Fd9txo4xjf5wukxi9pfp3.png" alt="TFC Cloud Organization" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And set it's value to the variable &lt;code&gt;$TF_CLOUD_ORGANIZATION&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Create need Terraform API Token that can be used to pull the outputs of terraform run(cloud). From your terraform user settings &lt;strong&gt;Create an API token&lt;/strong&gt;,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fob5t70rajo04jz5arjyd.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%2Fob5t70rajo04jz5arjyd.png" alt="Terraform API Token" width="799" height="245"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And save the API token to  the variable &lt;code&gt;$TF_TOKEN_app_terraform_io&lt;/code&gt;. We will use this variable in CI pipeline.&lt;/p&gt;

&lt;h2&gt;
  
  
  Harness CI Pipeline
&lt;/h2&gt;

&lt;p&gt;Getting back to Harness web console, navigate to your project &lt;strong&gt;terraform_integration_demos&lt;/strong&gt;, click &lt;strong&gt;Pipelines&lt;/strong&gt; and &lt;strong&gt;Create a Pipeline&lt;/strong&gt; --&amp;gt; &lt;strong&gt;Import From Git&lt;/strong&gt;,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhrnqdphbjmgjsn4jaaia.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%2Fhrnqdphbjmgjsn4jaaia.png" alt="New CI Pipeline Import" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Update the pipeline details as shown,&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%2F9cjbfq9n9akx1xcu21vl.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%2F9cjbfq9n9akx1xcu21vl.png" alt="Pipeline Details" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;IMPORTANT&lt;/strong&gt;: Make sure the &lt;strong&gt;Name&lt;/strong&gt; of the pipeline is &lt;code&gt;bootstrap argocd pipeline&lt;/code&gt; to make the import succeed with defaults.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmrr4uqouwsuwrw6ascw9.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%2Fmrr4uqouwsuwrw6ascw9.png" alt="Pipeline Import Successful" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click the &lt;code&gt;bootstrap argocd pipeline&lt;/code&gt; from the list to open the &lt;strong&gt;Pipeline Studio&lt;/strong&gt; and click on the stage &lt;strong&gt;Bootstrap Argo CD&lt;/strong&gt; to bring up the pipeline steps,&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%2Fbtazl7vzrl6n7r5y72ar.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%2Fbtazl7vzrl6n7r5y72ar.png" alt="Pipeline Steps" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can click on each step to see the details.&lt;/p&gt;

&lt;p&gt;The Pipeline uses the following secrets,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;google_application_credentials&lt;/code&gt; - the GSA credentials to manipulate GKE&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;terraform_cloud_api_token&lt;/code&gt; - the value of &lt;code&gt;$TF_TOKEN_app_terraform_io&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;terraform_workspace&lt;/code&gt; - the value &lt;code&gt;$TF_WORKSPACE&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;terraform_cloud_organization&lt;/code&gt; - the value &lt;code&gt;$TF_CLOUD_ORGANIZATION&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We already added &lt;code&gt;google_application_credentials&lt;/code&gt; secret as part of the earlier section. Following the similar pattern let us add the &lt;code&gt;terraform_cloud_api_token&lt;/code&gt;, &lt;code&gt;terraform_workspace&lt;/code&gt; and &lt;code&gt;terraform_cloud_organization&lt;/code&gt; as text secrets.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;HINT&lt;/strong&gt;:&lt;br&gt;
From the &lt;strong&gt;Project Setup&lt;/strong&gt; click &lt;strong&gt;Secrets&lt;/strong&gt;,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd21zbiyr2gdqjt4j0wrl.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%2Fd21zbiyr2gdqjt4j0wrl.png" alt="New Text Secret" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fslblnj5atbig84djnat8.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%2Fslblnj5atbig84djnat8.png" alt="all terraform secrets" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TIP&lt;/strong&gt;: You can also skip adding &lt;code&gt;terraform_workspace&lt;/code&gt; and &lt;code&gt;terraform_cloud_organization&lt;/code&gt;, we can extract the values from the webhook payload using the expressions &lt;code&gt;&amp;lt;+trigger.payload.workspace_name&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;+trigger.payload.organization_name&amp;gt;&lt;/code&gt; respectively.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Notification Trigger
&lt;/h2&gt;

&lt;p&gt;For the Harness CI pipelines to listen to Terraform Cloud Events we need to define a &lt;strong&gt;Trigger&lt;/strong&gt;, navigate back to pipelines and select the &lt;strong&gt;bootstrap argocd pipeline&lt;/strong&gt;  --&amp;gt; &lt;strong&gt;Triggers&lt;/strong&gt;,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwi19na36updy8iw0rbcx.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%2Fwi19na36updy8iw0rbcx.png" alt="Pipeline Triggers" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Add New Trigger&lt;/strong&gt; to add a new webhook trigger(Type: &lt;code&gt;Custom&lt;/code&gt;),&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F51m5842vy49r8j6v09mg.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%2F51m5842vy49r8j6v09mg.png" alt="Custom Webhook Trigger" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the &lt;strong&gt;Configuration&lt;/strong&gt; page enter the name of the trigger to be &lt;code&gt;tfc notification&lt;/code&gt;,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu7w3tjzgrnfjh7thfs7y.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%2Fu7w3tjzgrnfjh7thfs7y.png" alt="TFC Notification Config" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Leave rest of the fields to defaults and click &lt;strong&gt;Continue&lt;/strong&gt;, leave the &lt;strong&gt;Conditions&lt;/strong&gt; to defaults and click &lt;strong&gt;Continue&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;On the &lt;strong&gt;Pipeline Input&lt;/strong&gt; update the &lt;strong&gt;Pipeline Reference Branch&lt;/strong&gt; to be set to &lt;strong&gt;main&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdqc6h0c3zolmsk1e958v.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%2Fdqc6h0c3zolmsk1e958v.png" alt="Pipeline Input" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: The &lt;strong&gt;Pipeline Reference Branch&lt;/strong&gt; does not have any implication with this demo as we do manual clone of resources.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Click &lt;strong&gt;Create Trigger&lt;/strong&gt; to create and save the trigger.&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%2Fwb65schvss82ze38zeil.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%2Fwb65schvss82ze38zeil.png" alt="Trigger List" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Copy Webhook URL
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawr2qr1rbvl3sp96ng6f.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%2Fawr2qr1rbvl3sp96ng6f.png" alt="Webhook URL" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let us refer to this value as &lt;code&gt;$TRIGGER_WEBHOOK_URL&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Terraform Notification
&lt;/h2&gt;

&lt;p&gt;On your terraform cloud console navigate to the workspace &lt;strong&gt;Settings&lt;/strong&gt; --&amp;gt; &lt;strong&gt;Notifications&lt;/strong&gt;,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4dz8cfedh4l15eti8wyi.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%2F4dz8cfedh4l15eti8wyi.png" alt="TFC Notifications" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Create Notification&lt;/strong&gt; and select &lt;strong&gt;Webhook&lt;/strong&gt; as the &lt;strong&gt;Destination&lt;/strong&gt;,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvkuzrz1ooegbjhvan0ur.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%2Fvkuzrz1ooegbjhvan0ur.png" alt="Webhook" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Update the notification details as shown,&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%2Frthp02u6nqt1elqkya0x.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%2Frthp02u6nqt1elqkya0x.png" alt="TFC Webhook Details" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since we need to bootstrap argo CD only on create events we set the triggers to happen only on &lt;strong&gt;Completed&lt;/strong&gt;,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ztmiebchh4ybecx6pid.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%2F3ztmiebchh4ybecx6pid.png" alt="Trigger Events" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Create Notification&lt;/strong&gt; to finish the creation of notification.&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%2F5z8yl21d2uffup5u4ir5.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%2F5z8yl21d2uffup5u4ir5.png" alt="TFC Webhook Creation Success" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: The creation would have fired a notification, if the cluster is not ready yet the pipeline would have failed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Congratulations!!&lt;/strong&gt;. With this setup any new or updates thats done to the &lt;code&gt;$TFC_GKE_REPO&lt;/code&gt; will trigger a plan and apply on Terraform Cloud. A &lt;strong&gt;Completed&lt;/strong&gt; plan will trigger the &lt;code&gt;bootstrap argocd pipline&lt;/code&gt; to run and apply the manifests from &lt;code&gt;$BOOTSTRAP_ARGOCD_REPO&lt;/code&gt; on the GKE cluster.&lt;/p&gt;

&lt;p&gt;An example of successful pipeline run&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%2F1mxvq8tmtvi6hlhmzsd6.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%2F1mxvq8tmtvi6hlhmzsd6.png" alt="Pipeline Success" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;By using the terraform notifications feature we were able to make the CI pipelines listen to IaC events and run the CI pipelines as needed.&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%2Fa56swhyp5lzm9n5d9kpr.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%2Fa56swhyp5lzm9n5d9kpr.png" alt="Notification Pattern" width="799" height="491"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Using Workload Identity Continuous Integration(CI) Pipelines</title>
      <dc:creator>Kamesh Sampath</dc:creator>
      <pubDate>Thu, 23 Mar 2023 05:22:53 +0000</pubDate>
      <link>https://dev.to/kameshsampath/using-workload-identity-continuous-integrationci-pipelines-1dh5</link>
      <guid>https://dev.to/kameshsampath/using-workload-identity-continuous-integrationci-pipelines-1dh5</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;In the &lt;a href="https://dev.to/kameshsampath/what-is-workload-identity--120l"&gt;first part&lt;/a&gt; of this series we understood what a &lt;strong&gt;Workload Identity&lt;/strong&gt; is and in the &lt;a href="https://dev.to/kameshsampath/applying-workload-identity-with-a-demo-1bf9"&gt;second part&lt;/a&gt; how it can help in doing keyless Google API invocations by deploying a demo application. In this blog we learn how to use  &lt;strong&gt;Workload Identity&lt;/strong&gt; with SaaS Continuous Integration(&lt;strong&gt;CI&lt;/strong&gt;) providers.&lt;/p&gt;

&lt;p&gt;Many SaaS Continuous Integration(&lt;strong&gt;CI&lt;/strong&gt;) providers e.g &lt;a href="https://app.harness.io/auth/#/signup/?module=ci?utm_source=internal&amp;amp;utm_medium=social&amp;amp;utm_campaign=community&amp;amp;utm_content=kamesh-wi-delegate&amp;amp;utm_term=tutorial" rel="noopener noreferrer"&gt;Harness CI&lt;/a&gt; uses what is called a &lt;a href="https://developer.harness.io/docs/platform/Delegates/get-started-with-delegates/delegates-overview" rel="noopener noreferrer"&gt;&lt;strong&gt;Delegate&lt;/strong&gt;&lt;/a&gt; &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Harness Delegate is a service you run in your local laptop or on Cloud to connect your artifacts, infrastructure, collaboration, verification and other providers, with Harness Manager.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here are some advantages of using Delegates,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Total control of source code, as they can be within organisations cloud infrastructure&lt;/li&gt;
&lt;li&gt;Cloud Cost Optimisations as CI pipelines can leverage organisations existing cloud infrastructure&lt;/li&gt;
&lt;li&gt;Leverage the native cloud services from CI pipelines&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this tutorial we will deploy a Harness Delegate on to GKE and understand how enabling Workload Identity on GKE can simplify the CI Pipeline.&lt;/p&gt;

&lt;h2&gt;
  
  
  CI Pipeline UseCase
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Builds &lt;a href="https://go.dev/" rel="noopener noreferrer"&gt;go&lt;/a&gt; application, ideally you can build any application but go is taken as an example here.&lt;/li&gt;
&lt;li&gt;Package application build artifact as a container image&lt;/li&gt;
&lt;li&gt;Push the image to &lt;a href="https://cloud.google.com/artifact-registry/" rel="noopener noreferrer"&gt;Google Artifact Registry(&lt;strong&gt;GAR&lt;/strong&gt;)&lt;/a&gt;. &lt;/li&gt;
&lt;li&gt;Cache the build artifacts, dependencies(go modules) on to &lt;a href="https://cloud.google.com/storage/" rel="noopener noreferrer"&gt;Google Cloud Storage(&lt;strong&gt;GCS&lt;/strong&gt;)&lt;/a&gt; to make build process faster and quicker.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tutorial
&lt;/h2&gt;

&lt;p&gt;Before we get to tutorial make sure you have signed up for free tier &lt;a href="https://app.harness.io/auth/#/signup/?module=ci&amp;amp;utm_source=internal&amp;amp;utm_medium=social&amp;amp;utm_campaign=community&amp;amp;utm_content=kamesh-wi-delegate&amp;amp;utm_term=tutorial" rel="noopener noreferrer"&gt;Harness CI&lt;/a&gt; account.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pre-requisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A &lt;a href="https://cloud.google.com" rel="noopener noreferrer"&gt;Google Cloud Account&lt;/a&gt; with a Service Account with roles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Kubernetes Engine Admin&lt;/code&gt; - to create GKE cluster&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Service Account&lt;/code&gt; roles used to create/update/delete Service Account

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;iam.serviceAccounts.actAs&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;iam.serviceAccounts.get&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;iam.serviceAccounts.create&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;iam.serviceAccounts.delete&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;iam.serviceAccounts.update&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;iam.serviceAccounts.get&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;iam.serviceAccounts.getIamPolicy&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;iam.serviceAccounts.setIamPolicy&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;(OR) simply you can add &lt;code&gt;Service Account Admin&lt;/code&gt; and &lt;code&gt;Service Account User&lt;/code&gt; roles&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Compute Network Admin&lt;/code&gt;   - to create the VPC networks&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://cloud.google.com/sdk" rel="noopener noreferrer"&gt;Google Cloud SDK&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://terraform.build" rel="noopener noreferrer"&gt;terraform&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://kubernetes.io/docs/tasks/tools/" rel="noopener noreferrer"&gt;kubectl&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://helm.sh" rel="noopener noreferrer"&gt;helm&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://taskfile.dev" rel="noopener noreferrer"&gt;Taskfile&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Download Sources
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/harness-apps/workload-identity-gke-demo.git &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;basename&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$_&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; .git&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;DEMO_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PWD&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Environment Setup
&lt;/h3&gt;

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

&lt;p&gt;When working with Google Cloud the following environment variables helps in setting the right Google Cloud context like Service Account Key file, project etc., You can use &lt;a href="https://direnv.net" rel="noopener noreferrer"&gt;direnv&lt;/a&gt; or set the following variables on your shell,&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;export &lt;/span&gt;&lt;span class="nv"&gt;GOOGLE_APPLICATION_CREDENTIALS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"the google cloud service account key json file to use"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;CLOUDSDK_ACTIVE_CONFIG_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"the google cloud cli profile to use"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;GOOGLE_CLOUD_PROJECT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"the google cloud project to use"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;KUBECONFIG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DEMO_HOME&lt;/span&gt;&lt;span class="s2"&gt;/.kube/config"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can find more information about gcloud cli configurations at &lt;a href="https://cloud.google.com/sdk/docs/configurations" rel="noopener noreferrer"&gt;https://cloud.google.com/sdk/docs/configurations&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As you may need to override few terraform variables that you don't want to check in to VCS, add them to a file called &lt;code&gt;.local.tfvars&lt;/code&gt; and set the following environment variable to be picked up by terraform runs,&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;export &lt;/span&gt;&lt;span class="nv"&gt;TFVARS_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;.local.tfvars
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the &lt;a href="https://github.com/harness-apps/workload-identity-gke-demo#inputs" rel="noopener noreferrer"&gt;Inputs&lt;/a&gt; section for all possible terraform variables that are configurable.&lt;/p&gt;

&lt;p&gt;An example &lt;code&gt;.local.tfvars&lt;/code&gt; looks like,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;project_id&lt;/span&gt;                 &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"my-awesome-gcp-project"&lt;/span&gt;
&lt;span class="nx"&gt;region&lt;/span&gt;                     &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"asia-south1"&lt;/span&gt;
&lt;span class="nx"&gt;cluster_name&lt;/span&gt;               &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"wi-demos"&lt;/span&gt;
&lt;span class="nx"&gt;kubernetes_version&lt;/span&gt;         &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"1.24."&lt;/span&gt;
&lt;span class="nx"&gt;harness_account_id&lt;/span&gt;         &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"REPLACE WITH YOUR HARNESS ACCOUNT ID"&lt;/span&gt;
&lt;span class="nx"&gt;harness_delegate_token&lt;/span&gt;     &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"REPLACE WITH YOUR HARNESS DELEGATE TOKEN"&lt;/span&gt;
&lt;span class="nx"&gt;harness_delegate_name&lt;/span&gt;      &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"wi-demos-delegate"&lt;/span&gt;
&lt;span class="nx"&gt;harness_delegate_namespace&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"harness-delegate-ng"&lt;/span&gt;
&lt;span class="nx"&gt;harness_manager_endpoint&lt;/span&gt;   &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"https://app.harness.io/gratis"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create Environment
&lt;/h3&gt;

&lt;p&gt;We will use terraform to create a GKE cluster with &lt;code&gt;WorkloadIdentity&lt;/code&gt; enabled for its nodes,&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create GKE cluster
&lt;/h3&gt;

&lt;p&gt;The terraform apply will creates a GKE Cluster,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;task create_cluster
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Deploy Harness Delegate
&lt;/h3&gt;

&lt;p&gt;The following section deploys a Harness Delegate on to our GKE cluster. To be able to successfully deploy a Harness Delegate we need update the following values in our &lt;code&gt;.local.tfvars&lt;/code&gt; file,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;harness_account_id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;harness_delegate_token&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;harness_delegate_namespace&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;harness_manager_endpoint&lt;/code&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use &lt;strong&gt;Account Id&lt;/strong&gt; from Account Overview as the value for &lt;strong&gt;harness_account_id&lt;/strong&gt;,&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feom3g1bo25v0rc1iehjl.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%2Feom3g1bo25v0rc1iehjl.png" alt="account details" width="800" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use the &lt;strong&gt;Harness Cluster Hosting Account&lt;/strong&gt; from the account details to find the matching endpoint URL. e.g for &lt;code&gt;prod-2&lt;/code&gt; it is &lt;a href="https://app.harness.io/gratis" rel="noopener noreferrer"&gt;https://app.harness.io/gratis&lt;/a&gt; and set that as value for &lt;code&gt;harness_manager_endpoint&lt;/code&gt;. &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;TIP: &lt;br&gt;
You can find the endpoint corresponding to your &lt;strong&gt;Harness Cluster Hosting Account&lt;/strong&gt; from &lt;a href="https://developer.harness.io/tutorials/platform/install-delegate/" rel="noopener noreferrer"&gt;https://developer.harness.io/tutorials/platform/install-delegate/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Copy the default token from &lt;strong&gt;Projects&lt;/strong&gt; --&amp;gt; &lt;strong&gt;Project Setup&lt;/strong&gt; --&amp;gt; &lt;strong&gt;Delegates&lt;/strong&gt;(&lt;strong&gt;Tokens&lt;/strong&gt;) and set it as value for &lt;code&gt;harness_delegate_token&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr0y1vxdxunxal3li1xug.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%2Fr0y1vxdxunxal3li1xug.png" alt="copy default token" width="800" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;harness_delegate_name&lt;/code&gt;: defaults to &lt;strong&gt;harness-delegate&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;harness_delegate_namespace&lt;/code&gt;: defaults to &lt;strong&gt;harness-delegate-ng&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With us having updated the &lt;code&gt;.local.tfvars&lt;/code&gt;, run the following command to deploy the Harness Delegate,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;task deploy_harness_delegate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;NOTE: It will take some time for delegate to come up and get connected.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Wait for the delegate to be connected before proceeding to next steps. &lt;/p&gt;

&lt;p&gt;You can view status of the delegate from the &lt;strong&gt;Project&lt;/strong&gt; --&amp;gt; &lt;strong&gt;Project Setup&lt;/strong&gt; --&amp;gt; &lt;strong&gt;Delegates&lt;/strong&gt; page,&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%2Fyrjd9xd1k3r2pa6g35c3.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%2Fyrjd9xd1k3r2pa6g35c3.png" alt="delegate status" width="800" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also check the running Harness delegate pods by using &lt;code&gt;kubectl&lt;/code&gt;,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get pods &lt;span class="nt"&gt;-n&lt;/span&gt; harness-delegate-ng    
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output should be something like the pod name may vary based on your &lt;code&gt;harness_delegate_name&lt;/code&gt; value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NAME                                 READY   STATUS    RESTARTS   AGE
harness-delegate-6bfd78d5cb-5h8x9   1/1     Running   0          2m23s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Build Application
&lt;/h3&gt;

&lt;p&gt;Having deployed the Harness delegate, let us build a CI pipeline that will build and push the same &lt;a href="https://github.com/harness-apps/workload-identity-gke-demo/tree/main/app" rel="noopener noreferrer"&gt;go app&lt;/a&gt; to GAR.&lt;/p&gt;

&lt;h4&gt;
  
  
  Import Template
&lt;/h4&gt;

&lt;p&gt;The sources already has &lt;a href="https://github.com/harness-apps/workload-identity-gke-demo/blob/main/.harness/ko_gar_build_push_1.yaml" rel="noopener noreferrer"&gt;build stage&lt;/a&gt; template that can be used to create the CI pipeline.&lt;/p&gt;

&lt;p&gt;Navigate to your Harness Account, &lt;strong&gt;Account Overview&lt;/strong&gt; --&amp;gt; &lt;strong&gt;Organizations&lt;/strong&gt; and select &lt;strong&gt;default&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj07f38navg5c3udfjwan.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%2Fj07f38navg5c3udfjwan.png" alt="default org select" width="800" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the Organization overview page select &lt;strong&gt;Templates&lt;/strong&gt;,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2nii2f5wqwsr8lkvo5l1.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%2F2nii2f5wqwsr8lkvo5l1.png" alt="templates select" width="800" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;New Template&lt;/strong&gt; and choose &lt;strong&gt;Import From Git&lt;/strong&gt; option,&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%2Fme4lm1hzsqhuygwoid4t.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%2Fme4lm1hzsqhuygwoid4t.png" alt="import from git" width="800" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fill the wizard with values as shown,&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%2Fiff39t3r5tmaxr1fcrem.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%2Fiff39t3r5tmaxr1fcrem.png" alt="import from git details" width="800" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: If you want to use your fork of &lt;code&gt;harness-apps/workload-identity-gke-demo&lt;/code&gt; then update &lt;em&gt;Repository&lt;/em&gt; with your fork.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0grrjx3t1mq74xje7tg0.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%2F0grrjx3t1mq74xje7tg0.png" alt="import template successful" width="800" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Create Pipeline
&lt;/h2&gt;

&lt;p&gt;Navigate to &lt;strong&gt;Builds&lt;/strong&gt; --&amp;gt; &lt;strong&gt;Pipelines&lt;/strong&gt;, click &lt;strong&gt;Create Pipeline&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr5cyqbs2xb43l9uzyt2f.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%2Fr5cyqbs2xb43l9uzyt2f.png" alt="create pipeline" width="800" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Add Stage&lt;/strong&gt; and click &lt;strong&gt;Use template&lt;/strong&gt;, choose &lt;strong&gt;ko_gar_build_push&lt;/strong&gt; template that we imported earlier and click &lt;strong&gt;Use template&lt;/strong&gt; to complete import.&lt;/p&gt;

&lt;p&gt;Enter details about the stage,&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%2Fma34ba7s3dqw0y8qqlm1.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%2Fma34ba7s3dqw0y8qqlm1.png" alt="stage details" width="800" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Setup Stage&lt;/strong&gt; to create the stage and fill other details i.e &lt;strong&gt;Template Inputs&lt;/strong&gt;,&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr6crm2c5ygs72juades6.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%2Fr6crm2c5ygs72juades6.png" alt="template inputs" width="800" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We use &lt;code&gt;default&lt;/code&gt; namespace to run builder pods. The build pod runs with a Kubernetes Service Account(KSA) &lt;code&gt;harness-builder&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;:&lt;br&gt;
The &lt;code&gt;harness-builder&lt;/code&gt; KSA is mapped to Google IAM Service Account(GSA) &lt;code&gt;harness-delegate&lt;/code&gt; to inherit the GCP roles using Workload Identity in this case to push the images to Google Artifact Registry(GAR).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Click &lt;strong&gt;Run&lt;/strong&gt; to run the pipeline to see the image build and pushed to GAR,&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%2Fkbidxfctui4b3zmmoyuv.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%2Fkbidxfctui4b3zmmoyuv.png" alt="Run Pipeline" width="800" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As successful run would have pushed the image into GAR in this example its &lt;code&gt;asia-south1-docker.pkg.dev/pratyakshika/demos/lingua-greeter:latest&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhlo8z6klt1qtfidzgn8h.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%2Fhlo8z6klt1qtfidzgn8h.png" alt="Build Success" width="800" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Cleanup
&lt;/h2&gt;

&lt;p&gt;To clean up all the Google Cloud resources that were created as part of this demo,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;task destroy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;By using Workload Identity Delegate we have simplified and secured our CI pipelines which can now use any Google API services by configuring the GSA with right roles/permissions. The CI SaaS platform no longer need to store/update the Google API credentials.&lt;/p&gt;

&lt;p&gt;Having deployed Workload Identity Delegate you can also do &lt;a href="https://docs.sigstore.dev/cosign/sign/#keyless-signing" rel="noopener noreferrer"&gt;keyless signing&lt;/a&gt; of your container images using Google Application Credentials. For more info check &lt;a href="https://sigstore.dev" rel="noopener noreferrer"&gt;cosign&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For more tutorials and documentation please visit &lt;a href="https://developer.harness.io" rel="noopener noreferrer"&gt;https://developer.harness.io&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
