<?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: Lavakush biyani ☄</title>
    <description>The latest articles on DEV Community by Lavakush biyani ☄ (@lavkushbiyani1).</description>
    <link>https://dev.to/lavkushbiyani1</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%2F783437%2F6ab7adef-2a31-438b-9738-c960d6327dff.jpg</url>
      <title>DEV Community: Lavakush biyani ☄</title>
      <link>https://dev.to/lavkushbiyani1</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lavkushbiyani1"/>
    <language>en</language>
    <item>
      <title>Stop Letting Deployment Approvals Slow Down Your Releases</title>
      <dc:creator>Lavakush biyani ☄</dc:creator>
      <pubDate>Thu, 15 Oct 2026 11:03:12 +0000</pubDate>
      <link>https://dev.to/lavkushbiyani1/stop-letting-deployment-approvals-slow-down-your-releases-6gh</link>
      <guid>https://dev.to/lavkushbiyani1/stop-letting-deployment-approvals-slow-down-your-releases-6gh</guid>
      <description>&lt;p&gt;TL;DR&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Approvals shouldn’t cost you a shift. With Harness, the approval step lives inside your pipeline, so you get sign-off without the waiting and the glue code.&lt;/li&gt;
&lt;li&gt;Key takeaways include:&lt;/li&gt;
&lt;li&gt;Waiting on people is the real cost: Approval gates rarely fail because the check is wrong. They fail because someone isn’t free when the deploy needs them, and those hours add up fast.&lt;/li&gt;
&lt;li&gt;Keep approvals in the pipeline: One approval step runs alongside your build and deploy. No separate tool, no webhook to wire up.&lt;/li&gt;
&lt;li&gt;Measure ready-to-release time: Track the gap between staging validation and the next deployment, find where approvals stall, and fix that.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Approval Gate That Costs You a Shift
&lt;/h2&gt;

&lt;p&gt;Manual approval gates in front of the pre-prod stage don't fail because the check is wrong. They fail because they wait on a person, and a person isn't always available the moment a deployment needs one. A build that passes staging tests at 10 AM can sit blocked for hours waiting on a checklist that requires three separate sign-offs before anyone can click “Approve”. By the time all three land, it's 6 PM, the engineer who owns the next step has already left for the day, and the deployment slips to the next morning.&lt;/p&gt;

&lt;p&gt;That's not a one-off. Across 12 releases last quarter, the same 4-hour-plus wait recurred, adding up to roughly two full working days of cycle time spent waiting on sign-offs, not shipping anything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How a Single Execution ID helps&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A Harness pipeline is a single execution graph, not two tools glued together by a webhook. Your staging and pre-prod stages sit inside the same pipeline object, sharing a single execution ID and timeline. There's no artifact handed off from a CI system to a separate CD system via a trigger or webhook payload. The same pipeline orchestration layer that started the run owns it end-to-end, from the first step to the last. That matters for what comes next, because it means a later stage can reference an earlier stage's output directly through an expression.&lt;/p&gt;

&lt;p&gt;Bring the Approval Process Into the Pipeline&lt;br&gt;
With Harness, teams can build approval gates directly into their deployment pipelines instead of stitching together a separate workflow for every release. This step slots into the same Staging-to-Pre-production pipeline covered in &lt;a href="https://www.harness.io/blog/deploy-your-first-app-with-harness-cd" rel="noopener noreferrer"&gt;Deploy Your First App with Harness CD&lt;/a&gt;, right after the Deploy stage and before the pre-prod promotion. Once the staging checks are complete, the pipeline reaches the approval step. Harness notifies the configured reviewers, waits for the required approvals, and continues when the approval conditions are met.&lt;/p&gt;

&lt;p&gt;This is the whole step, no separate approval-tracking tool, no webhook to wire up. Drop it into any CD stage and point userGroups at your release managers:&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="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;step&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;HarnessApproval&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Release Manager Sign-Off&lt;/span&gt;
    &lt;span class="na"&gt;identifier&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ReleaseManagerSignOff&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;approvalMessage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|-&lt;/span&gt;
        &lt;span class="s"&gt;Review this release before it proceeds to pre-production.&lt;/span&gt;
      &lt;span class="na"&gt;includePipelineExecutionHistory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="na"&gt;approvers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;minimumCount&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
        &lt;span class="na"&gt;disallowPipelineExecutor&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
        &lt;span class="na"&gt;userGroups&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;account.release_managers&lt;/span&gt;
      &lt;span class="na"&gt;approverInputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[]&lt;/span&gt;
    &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;The approval step sits within the same execution graph as the build and deploy stages, not bolted on alongside them.&lt;/p&gt;

&lt;p&gt;Harness supports different approval approaches depending on how your organization works. A team can request direct sign-off through a Harness Approval step, use Jira Approval when the decision depends on a Jira issue, or use ServiceNow Approval when production changes are governed by a ServiceNow workflow. The Jira variant looks like this:&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="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;step&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;JiraApproval&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Change Request Approval&lt;/span&gt;
    &lt;span class="na"&gt;identifier&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ChangeRequestApproval&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;connectorRef&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;jira_connector&lt;/span&gt;
      &lt;span class="na"&gt;projectKey&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;REL&lt;/span&gt;
      &lt;span class="na"&gt;issueKey&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;+pipeline.variables.jira_ticket&amp;gt;&lt;/span&gt;
      &lt;span class="na"&gt;approvalCriteria&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;KeyValues&lt;/span&gt;
        &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;conditions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Status&lt;/span&gt;
              &lt;span class="na"&gt;operator&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;equals&lt;/span&gt;
              &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Approved&lt;/span&gt;

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

&lt;/div&gt;



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

&lt;p&gt;The approval criteria are tied directly to the Jira issue’s status field; no separate polling or webhook needed.&lt;/p&gt;

&lt;p&gt;The point is to fit the approval into the release process your organization already follows.&lt;/p&gt;

&lt;p&gt;Spend Less Time Chasing Approvals&lt;br&gt;
An approval request shouldn't leave reviewers wondering what they're being asked to approve.&lt;/p&gt;

&lt;p&gt;When the relevant release context is readily available, reviewers can spend less time tracking down deployment details and more time making the decision. Teams can configure approvers, approval requirements, notifications, and timeouts to make the process more predictable.&lt;/p&gt;

&lt;p&gt;Timeouts also help define what happens when an approval doesn't arrive. Rather than leaving a release blocked indefinitely, teams can configure the pipeline's failure behavior to align with their release policies, and for organizations that require formal change management, Jira and ServiceNow approval integrations can connect the deployment workflow to the relevant change request.&lt;/p&gt;

&lt;p&gt;The result is a more consistent approval process, without requiring teams to build and maintain a custom approval mechanism for every 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvk9v972qfodfn0pvf7dy.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%2Fvk9v972qfodfn0pvf7dy.png" alt=" " width="800" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Approval status sits right inside the pipeline execution&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep Human Judgment Where It Matters&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not every release decision needs a person. Test results, artifact requirements, and other machine-verifiable conditions can often be checked automatically before an approval request is raised. Human approval can then focus on decisions that require accountability, business context, or explicit authorization.&lt;/p&gt;

&lt;p&gt;Harness Policy as Code can be added when teams need custom, enforceable rules for release readiness. But when the requirement is simply to obtain a human sign-off, a native Harness Approval step is often all that's needed.&lt;/p&gt;

&lt;p&gt;The distinction matters: automating the checks reduces manual verification, while streamlining the approval workflow makes it easier for the right people to act.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Measure the Time Between Ready and Released&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The real measure of an approval workflow isn't how quickly a button can be clicked. It's how long a release waits after it's technically ready to move forward. Track the time between the completion of staging validation and the start of the next deployment. Look for recurring delays, identify where approvals get stuck, and use those findings to improve the workflow.&lt;/p&gt;

&lt;p&gt;If your current process regularly adds hours of waiting, set a measurable improvement target and validate it against actual execution data. A release pipeline should make necessary controls easier to follow, not turn coordination into the longest stage of the delivery process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next up:&lt;/strong&gt; Encoding release-readiness as Policy as Code. Once the sign-off step itself is fast, the next bottleneck is usually the checklist behind it: test status, artifact tag, ticket linkage, still being checked by eye. We’ll cover how to turn that checklist into an &lt;a href="https://developer.harness.io/harness-platform/use-harness-platform/governance/policy-as-code/add-a-governance-policy-step-to-a-pipeline" rel="noopener noreferrer"&gt;enforced OPA policy&lt;/a&gt; in the next piece.&lt;/p&gt;

&lt;p&gt;Ready to streamline deployment approvals? Explore &lt;a href="https://developer.harness.io/harness-platform/use-harness-platform/approvals/adding-harness-approval-stages" rel="noopener noreferrer"&gt;Harness Approval steps&lt;/a&gt; and see how they fit into your existing delivery workflow. If you’re starting from scratch, &lt;a href="https://app.harness.io/auth/#/signin" rel="noopener noreferrer"&gt;sign up&lt;/a&gt; for a free Harness account first, no credit card required.&lt;/p&gt;

</description>
      <category>automation</category>
      <category>cicd</category>
      <category>deployment</category>
      <category>devops</category>
    </item>
    <item>
      <title>Deploy Your First App with Harness CD in Under 15 Minutes</title>
      <dc:creator>Lavakush biyani ☄</dc:creator>
      <pubDate>Fri, 09 Oct 2026 05:14:57 +0000</pubDate>
      <link>https://dev.to/lavkushbiyani1/deploy-your-first-app-with-harness-cd-in-under-15minutes-2618</link>
      <guid>https://dev.to/lavkushbiyani1/deploy-your-first-app-with-harness-cd-in-under-15minutes-2618</guid>
      <description>&lt;p&gt;&lt;strong&gt;Who this is for:&lt;/strong&gt; Developers or platform engineers who have never run a Harness CD pipeline before. You'll need an SCM account, a Docker Hub (or similar) account, a Kubernetes cluster that a Harness Delegate can reach, and a Harness account. Once the delegate is connected, everything else in this walkthrough happens inside the Harness platform.&lt;/p&gt;

&lt;p&gt;The problem with your first deployment&lt;/p&gt;

&lt;p&gt;Most teams first few production deployments look the same: SSH into a container, git pull, rebuild, restart the service, and watch the logs for a minute to see if anything screams. It works, right up until it doesn't. A bad build ships, nobody's sure which commit is actually running, and rolling back means remembering the last image tag that worked and doing the whole manual process again, under pressure, at the worst possible time. That's usually 15-20 minutes of frantic SSH for something a rollback button should do in seconds.&lt;/p&gt;

&lt;p&gt;That's not a tooling failure so much as a missing layer. Builds are automated. Deployments still aren't for many teams.&lt;/p&gt;

&lt;p&gt;Two ways people usually solve this&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hand-roll it in your CI tool:&lt;/strong&gt; If you're already on GitHub Actions, GitLab CI, or Jenkins, the path of least resistance is to bolt a deploy step onto the end of your build job: kubectl apply or a shell script over SSH. This is genuinely fine for a single service, a single environment, and a single person who understands the script. It stops being fine the moment you need a second environment, a rollback that doesn't involve re-running a script from memory, or an approval gate before production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Adopt a dedicated CD tool:&lt;/strong&gt; Splitting build (CI) from deploy (CD) means that the deployment itself, the environment it targets, the strategy it uses, and what happens if it fails become something you configure once and reuse, rather than being re-implemented in every pipeline's YAML. That's the trade you're making by picking this path: a bit more setup up front, in exchange for rollback, approvals, and audit history you don't have to build yourself.&lt;/p&gt;

&lt;p&gt;We'll use Harness CD for the deep dive below, deploying a real Java application to a Kubernetes cluster. CD is one piece of Harness's broader Software Delivery Agent; the same governance and audit trail you'll see here also covers builds, infra, and artifacts, so this pipeline slots into a bigger picture rather than being a one-off tool.&lt;/p&gt;

&lt;p&gt;Deploying the Sample Application with Harness CD&lt;/p&gt;

&lt;p&gt;We're using the &lt;a href="https://github.com/harness-community/harness-sample-apps/tree/main/easybuggy-vulnerable-application" rel="noopener noreferrer"&gt;easybuggy-vulnerable-application&lt;/a&gt; as the sample application. It's a small Java/Tomcat app, and it already ships a working Dockerfile. The repo also has a .harness/ folder with a working pipeline definition already checked in. If you want the fast path, point Harness at that folder directly and skip to step 7. Otherwise, follow the steps below to build it yourself by hand, then compare what you built against that folder afterward.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Clone the repo and build the image&lt;/strong&gt;&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/harness-community/harness-sample-apps.git
&lt;span class="nb"&gt;cd &lt;/span&gt;harness-sample-apps/easybuggy-vulnerable-application

docker build &lt;span class="nt"&gt;-t&lt;/span&gt; &amp;lt;your-dockerhub-username&amp;gt;/easybuggy:v1 &lt;span class="nb"&gt;.&lt;/span&gt;
docker push &amp;lt;your-dockerhub-username&amp;gt;/easybuggy:v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the push succeeds, you'll see something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;v1: digest: sha256:9f3a1c... size: 1786
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That artifact digest is your proof that the image actually landed in the registry.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Point Harness at your cluster and your registry&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In your Harness project, go to Project Settings → Connectors and create:&lt;/p&gt;

&lt;p&gt;Docker Registry connector: A Docker Registry connector pointing at Docker Hub, using the same credentials you just pushed with.&lt;/p&gt;

&lt;p&gt;Kubernetes Cluster connector: A Kubernetes Cluster connector pointing to the cluster you'll deploy to (your local kind cluster or a free-tier cluster works fine here). If you don't already have a Harness Delegate running in that cluster, the connector setup walks you through installing one: a lightweight agent that lets Harness reach the cluster and run deployments against it. Harness will hand you a helm install command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;helm repo add harness-delegate https://app.harness.io/storage/harness-download/delegate-helm-chart/ 
helm &lt;span class="nb"&gt;install &lt;/span&gt;my-delegate harness-delegate/harness-delegate-ng &lt;span class="se"&gt;\&lt;/span&gt;
&amp;nbsp;--namespace harness-delegate-ng &lt;span class="nt"&gt;--create-namespace&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
 &lt;span class="nt"&gt;--set&lt;/span&gt; &lt;span class="nv"&gt;delegateName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;easybuggy-delegate &lt;span class="se"&gt;\&lt;/span&gt;
 &lt;span class="nt"&gt;--set&lt;/span&gt; &lt;span class="nv"&gt;accountId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;your-account-id&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
 &lt;span class="nt"&gt;--set&lt;/span&gt; &lt;span class="nv"&gt;delegateToken&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;your-delegate-token&amp;gt;

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

&lt;/div&gt;



&lt;p&gt;Once that pod is running in your cluster, the Delegates page in Harness (Project Settings → Delegates) will show it as Connected. That status, checked from within Harness, is your confirmation that Harness can reach the cluster; you don't need to inspect the cluster directly to know it worked.&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%2F4cunrhsp6ro55usox3hh.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%2F4cunrhsp6ro55usox3hh.png" alt=" " width="800" height="232"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Define the Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A Harness Service is just "what am I deploying, and what does it look like when it's running." Create one &lt;a href="https://developer.harness.io/continuous-delivery/use-continuous-delivery/cd-building-blocks/services/create-services" rel="noopener noreferrer"&gt;service&lt;/a&gt; and give it two things: an artifact source (your Docker Registry connector, image easybuggy, tag v1) and a Kubernetes manifest. A bare bones manifest YAML for this app looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;easybuggy&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;easybuggy&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;easybuggy&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;easybuggy&lt;/span&gt;
          &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;+artifact.image&amp;gt;&lt;/span&gt;
          &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8080&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;easybuggy-svc&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;easybuggy&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8080&lt;/span&gt;
      &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8080&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;LoadBalancer&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The _&amp;lt;+artifact.image&amp;gt; _placeholder is Harness variable syntax. At deploy time, it's swapped for whatever image and tag you configured as the artifact source. See adding container images as artifacts for Kubernetes deployments for the full reference on wiring an artifact into a manifest this way. It's also how promoting a build from staging to production later becomes a config change instead of a YAML edit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Define the Environment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A Harness Environment is the named target you're deploying to: dev, staging, or prod. It's kept separate from the Service on purpose, so the same "what am I deploying" definition from step 3 can be promoted through multiple environments later without being rewritten for each one. Create one &lt;a href="https://developer.harness.io/continuous-delivery/use-continuous-delivery/cd-building-blocks/environments/create-environments" rel="noopener noreferrer"&gt;infrastructure&lt;/a&gt; and call it dev.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Define the Infrastructure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Under that Environment, add an Infrastructure Definition. This is the specific place the deployment lands: pick Kubernetes, point it to the cluster connector from step 2, and set the namespace you want to deploy to (the default is fine for a first run).&lt;/p&gt;

&lt;p&gt;If step 4 answers "which environment," this answers "which cluster and namespace, specifically."&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%2Fucmk9jqlzeorzffsd87f.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%2Fucmk9jqlzeorzffsd87f.png" alt=" " width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Build the pipeline&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a pipeline with a single Deploy stage:&lt;/p&gt;

&lt;p&gt;Service: the one you just defined&lt;br&gt;
Environment: dev&lt;br&gt;
Execution strategy: Rolling. Harness generates the deploy steps for you; you don't need to hand-write this part.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Run it&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hit Run Pipeline. You'll watch a live console log scroll through roughly this shape:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx9n44uadr8dz9ktertc7.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx9n44uadr8dz9ktertc7.gif" alt=" " width="600" height="343"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Common first-run snags&lt;/p&gt;

&lt;p&gt;A few things trip up almost every first Harness CD pipeline. Worth checking before you assume the pipeline itself is broken:&lt;/p&gt;

&lt;p&gt;Delegate stays stuck on "Not Connected." Give it 60 to 90 seconds after the pod starts; the delegate needs to finish registering with Harness before a connector test connection will pass.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Image pull errors in the pod events:&lt;/strong&gt; These show up in the execution log for the deploy step. Double-check the Docker Registry connector's credentials match what you used for docker push, and confirm the tag in the Service's artifact source is exactly v1, not latest, unless you pushed latest.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pods are stuck in Pending:&lt;/strong&gt; This is almost always the cluster not having enough allocatable CPU or memory for two replicas at once. Drop replicas to 1 in the manifest and redeploy to confirm that's the cause.&lt;/p&gt;

&lt;p&gt;What "it worked" actually looks like&lt;/p&gt;

&lt;p&gt;Two things prove this deployment did what it claims to have done, and neither one is a feeling:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pipeline execution view:&lt;/strong&gt; Every step green, a deploy log tied to a specific commit and image digest, and a timestamp. That's your audit trail, and it exists whether or not anyone was watching when it ran.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Safety net test:&lt;/strong&gt; Roll something bad on purpose to see the safety net work. Push a tag that intentionally fails (an image name with a typo is enough), point the pipeline at it, and run it again. Harness will fail the rollout and mark the deployment for rollback: no SSH session. That one-click rollback is the actual point of this whole exercise. It's the difference between a deploy tool and a deploy script.&lt;/p&gt;

&lt;p&gt;Once you've watched both a clean rollout and a rollback happen once, the numbers that used to be tribal knowledge (who deployed this, what image is actually live, how do we get back to the last good version) become answers you can pull from the pipeline execution log.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Try it yourself&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Fork or clone &lt;a href="https://github.com/harness-community/harness-sample-apps/tree/main/easybuggy-vulnerable-application" rel="noopener noreferrer"&gt;easybuggy-vulnerable-application&lt;/a&gt;, point it at your own Kubernetes cluster, and run through the steps above end-to-end. &lt;a href="https://app.harness.io/auth/#/signin" rel="noopener noreferrer"&gt;Sign up &lt;/a&gt;for a free Harness account if you don't already have one; no credit card required.&lt;/p&gt;

&lt;p&gt;If you built the pipeline by hand rather than using the fast path, diff it against the repo's .harness/ folder to see what you'd automate next: Git-based pipeline sync instead of clicking through the UI.&lt;/p&gt;

&lt;p&gt;This walkthrough gets you a working rolling deployment to one environment. Next up: &lt;a href="https://developer.harness.io/harness-platform/use-harness-platform/approvals/adding-harness-approval-stages" rel="noopener noreferrer"&gt;Add a Canary Deployment and Approval Gate to This Pipeline&lt;/a&gt;. We'll take the same Service definition, promote it to a second environment with manual approval, and swap the Rolling strategy for Canary so that a bad build only ever hits a fraction of the traffic before it's caught.&lt;/p&gt;

</description>
      <category>automation</category>
      <category>cicd</category>
      <category>devops</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
