Marketplace

harness-cd

Harness CD (Continuous Delivery) for Kubernetes, Helm, Terraform, ECS, and serverless deployments with GitOps, approval gates, rollback strategies, and multi-environment promotion

allowed_tools: Bash, Read, Write, Edit, Glob, Grep, Task, WebFetch, WebSearch

$ Instalar

git clone https://github.com/Lobbi-Docs/claude /tmp/claude && cp -r /tmp/claude/.claude/plugins/jira-orchestrator/skills/harness-cd ~/.claude/skills/claude

// tip: Run this command in your terminal to install the skill


name: harness-cd description: Harness CD (Continuous Delivery) for Kubernetes, Helm, Terraform, ECS, and serverless deployments with GitOps, approval gates, rollback strategies, and multi-environment promotion allowed-tools:

  • Bash
  • Read
  • Write
  • Edit
  • Glob
  • Grep
  • Task
  • WebFetch
  • WebSearch dependencies:
  • harness-platform
  • harness-mcp triggers:
  • harness cd
  • harness deploy
  • harness deployment
  • harness rollback
  • harness canary
  • harness blue green
  • harness rolling
  • harness gitops
  • harness environment
  • harness infrastructure
  • harness service
  • harness artifact
  • harness approval
  • deployment strategy
  • kubernetes deployment
  • helm deployment
  • terraform deployment

Harness CD Skill

Comprehensive Harness CD (Continuous Delivery) for deployments across Kubernetes, Helm, Terraform, ECS, serverless, and traditional platforms with GitOps support.

When to Use This Skill

Activate this skill when:

  • Creating or managing Harness CD pipelines
  • Configuring deployment strategies (Canary, Blue-Green, Rolling)
  • Setting up environments and infrastructure definitions
  • Managing services and artifacts
  • Configuring approval gates and governance
  • Implementing GitOps workflows
  • Setting up deployment verification and rollback
  • Managing multi-environment promotion
  • Troubleshooting deployment failures

CD Pipeline Structure

Basic Deployment Pipeline

pipeline:
  name: Deploy Pipeline
  identifier: deploy_pipeline
  projectIdentifier: my_project
  orgIdentifier: default
  stages:
    - stage:
        name: Deploy to Dev
        identifier: deploy_dev
        type: Deployment
        spec:
          deploymentType: Kubernetes
          service:
            serviceRef: my_service
          environment:
            environmentRef: development
            infrastructureDefinitions:
              - identifier: dev_k8s
          execution:
            steps:
              - step:
                  name: Rolling Deployment
                  identifier: rollingDeployment
                  type: K8sRollingDeploy
                  timeout: 10m
                  spec:
                    skipDryRun: false
            rollbackSteps:
              - step:
                  name: Rollback
                  identifier: rollback
                  type: K8sRollingRollback
                  timeout: 10m

Deployment Strategies

Rolling Deployment

Gradual replacement of instances:

- step:
    name: Rolling Deploy
    identifier: rolling
    type: K8sRollingDeploy
    spec:
      skipDryRun: false
      pruningEnabled: false

Canary Deployment

Progressive traffic shifting:

- stage:
    name: Canary Deploy
    identifier: canary
    type: Deployment
    spec:
      deploymentType: Kubernetes
      execution:
        steps:
          - stepGroup:
              name: Canary Deployment
              identifier: canaryDeployment
              steps:
                - step:
                    name: Canary Deployment
                    identifier: canaryDeploy
                    type: K8sCanaryDeploy
                    spec:
                      instanceSelection:
                        type: Count
                        spec:
                          count: 1
                      skipDryRun: false
                - step:
                    name: Canary Delete
                    identifier: canaryDelete
                    type: K8sCanaryDelete
                    spec: {}
          - stepGroup:
              name: Primary Deployment
              identifier: primaryDeployment
              steps:
                - step:
                    name: Rolling Deployment
                    identifier: rollingDeploy
                    type: K8sRollingDeploy
                    spec:
                      skipDryRun: false

Blue-Green Deployment

Zero-downtime with instant cutover:

- stage:
    name: Blue-Green Deploy
    identifier: blueGreen
    type: Deployment
    spec:
      deploymentType: Kubernetes
      execution:
        steps:
          - step:
              name: Stage Deployment
              identifier: stageDeployment
              type: K8sBGStageDeployment
              spec:
                skipDryRun: false
          - step:
              name: Swap Primary
              identifier: swapPrimary
              type: K8sBGSwapServices
              spec:
                skipDryRun: false
        rollbackSteps:
          - step:
              name: Swap Rollback
              identifier: swapRollback
              type: K8sBGSwapServices
              spec:
                skipDryRun: false

Service Configuration

Kubernetes Service

service:
  name: My Service
  identifier: my_service
  serviceDefinition:
    type: Kubernetes
    spec:
      manifests:
        - manifest:
            identifier: k8s_manifest
            type: K8sManifest
            spec:
              store:
                type: Git
                spec:
                  connectorRef: github_connector
                  gitFetchType: Branch
                  paths:
                    - k8s/
                  branch: main
      artifacts:
        primary:
          primaryArtifactRef: <+input>
          sources:
            - identifier: docker_image
              type: DockerRegistry
              spec:
                connectorRef: docker_connector
                imagePath: myorg/myapp
                tag: <+input>

Helm Service

service:
  name: Helm Service
  identifier: helm_service
  serviceDefinition:
    type: NativeHelm
    spec:
      manifests:
        - manifest:
            identifier: helm_chart
            type: HelmChart
            spec:
              store:
                type: Http
                spec:
                  connectorRef: helm_repo
              chartName: my-app
              chartVersion: <+input>
              helmVersion: V3
      artifacts:
        primary:
          primaryArtifactRef: docker_image
          sources:
            - identifier: docker_image
              type: DockerRegistry
              spec:
                connectorRef: docker_connector
                imagePath: myorg/myapp
                tag: <+input>

Terraform Service

service:
  name: Terraform Service
  identifier: terraform_service
  serviceDefinition:
    type: CustomDeployment
    spec:
      customDeploymentRef:
        templateRef: terraform_template
        versionLabel: v1

Environment Configuration

Environment Types

# Development
environment:
  name: Development
  identifier: development
  type: PreProduction
  orgIdentifier: default
  projectIdentifier: my_project

# Staging
environment:
  name: Staging
  identifier: staging
  type: PreProduction
  tags:
    tier: staging
    auto_deploy: "true"

# Production
environment:
  name: Production
  identifier: production
  type: Production
  tags:
    tier: production
    requires_approval: "true"

Infrastructure Definition

infrastructureDefinition:
  name: K8s Dev Cluster
  identifier: k8s_dev
  type: KubernetesDirect
  orgIdentifier: default
  projectIdentifier: my_project
  environmentRef: development
  spec:
    connectorRef: k8s_connector
    namespace: my-namespace
    releaseName: release-<+INFRA_KEY>

Approval Gates

Manual Approval

- step:
    name: Approval
    identifier: approval
    type: HarnessApproval
    timeout: 1d
    spec:
      approvalMessage: "Please review and approve deployment to production"
      includePipelineExecutionHistory: true
      approvers:
        userGroups:
          - account.ProductionApprovers
        minimumCount: 1
        disallowPipelineExecutor: true
      approverInputs:
        - name: releaseNotes
          defaultValue: ""

Jira Approval

- step:
    name: Jira Approval
    identifier: jiraApproval
    type: JiraApproval
    timeout: 1d
    spec:
      connectorRef: jira_connector
      projectKey: DEPLOY
      issueKey: <+pipeline.variables.jiraIssueKey>
      approvalCriteria:
        type: KeyValues
        spec:
          matchAnyCondition: true
          conditions:
            - key: Status
              operator: equals
              value: Approved
      rejectionCriteria:
        type: KeyValues
        spec:
          matchAnyCondition: true
          conditions:
            - key: Status
              operator: equals
              value: Rejected

ServiceNow Approval

- step:
    name: ServiceNow Approval
    identifier: snowApproval
    type: ServiceNowApproval
    timeout: 1d
    spec:
      connectorRef: servicenow_connector
      ticketNumber: <+pipeline.variables.changeRequest>
      ticketType: CHANGE_REQUEST
      approvalCriteria:
        type: KeyValues
        spec:
          conditions:
            - key: state
              operator: equals
              value: "3"  # Approved state

GitOps Deployments

Argo CD Integration

- stage:
    name: GitOps Deploy
    identifier: gitops_deploy
    type: Deployment
    spec:
      deploymentType: Kubernetes
      gitOpsEnabled: true
      execution:
        steps:
          - step:
              name: Update Release Repo
              identifier: updateReleaseRepo
              type: GitOpsUpdateReleaseRepo
              spec:
                variables:
                  - name: image_tag
                    value: <+artifact.tag>
          - step:
              name: Sync Application
              identifier: syncApp
              type: GitOpsFetchLinkedApps
              spec: {}
          - step:
              name: Sync and Wait
              identifier: syncWait
              type: GitOpsSync
              spec:
                prune: true
                dryRun: false
                applyOnly: false
                forceApply: false

PR-Based GitOps

- step:
    name: Create PR
    identifier: createPR
    type: CreatePR
    spec:
      connectorRef: github_connector
      repoName: gitops-config
      sourceBranch: release/<+pipeline.sequenceId>
      targetBranch: main
      title: "Deploy <+service.name> to <+env.name>"
      commitMessage: "Update image tag to <+artifact.tag>"
      updateType: Json
      updates:
        - path: environments/<+env.name>/values.yaml
          key: image.tag
          value: <+artifact.tag>

- step:
    name: Merge PR
    identifier: mergePR
    type: MergePR
    spec:
      connectorRef: github_connector
      prNumber: <+pipeline.stages.Deploy.spec.execution.steps.createPR.output.prNumber>
      deleteSourceBranch: true

Deployment Verification

Continuous Verification

- step:
    name: Verify Deployment
    identifier: verify
    type: Verify
    timeout: 2h
    spec:
      type: Canary
      monitoredService:
        type: Default
        spec: {}
      spec:
        sensitivity: MEDIUM
        duration: 15m
        deploymentTag: <+artifacts.primary.tag>

Health Checks

- step:
    name: HTTP Health Check
    identifier: healthCheck
    type: Http
    timeout: 5m
    spec:
      url: <+infra.variables.serviceUrl>/health
      method: GET
      assertion: <+httpResponseCode> == 200
      headers: []

Rollback Strategies

Automatic Rollback

execution:
  steps:
    - step:
        name: Deploy
        identifier: deploy
        type: K8sRollingDeploy
        spec:
          skipDryRun: false
  rollbackSteps:
    - step:
        name: Rollback
        identifier: rollback
        type: K8sRollingRollback
        timeout: 10m
        spec: {}
failureStrategies:
  - onFailure:
      errors:
        - AllErrors
      action:
        type: StageRollback

Manual Rollback

- step:
    name: Rollback Confirmation
    identifier: rollbackConfirm
    type: HarnessApproval
    spec:
      approvalMessage: "Approve rollback to previous version?"
      approvers:
        userGroups:
          - account.Deployers
- step:
    name: Execute Rollback
    identifier: executeRollback
    type: K8sRollingRollback
    spec: {}

Multi-Environment Promotion

Environment Pipeline

pipeline:
  name: Multi-Env Deploy
  identifier: multi_env_deploy
  stages:
    - stage:
        name: Deploy to Dev
        identifier: deploy_dev
        type: Deployment
        spec:
          deploymentType: Kubernetes
          environment:
            environmentRef: development

    - stage:
        name: Deploy to Staging
        identifier: deploy_staging
        type: Deployment
        spec:
          deploymentType: Kubernetes
          environment:
            environmentRef: staging
        when:
          pipelineStatus: Success
          condition: <+pipeline.stages.deploy_dev.status> == "SUCCEEDED"

    - stage:
        name: Approval for Production
        identifier: prod_approval
        type: Approval
        spec:
          execution:
            steps:
              - step:
                  type: HarnessApproval
                  spec:
                    approvers:
                      userGroups:
                        - account.ProductionApprovers

    - stage:
        name: Deploy to Production
        identifier: deploy_prod
        type: Deployment
        spec:
          deploymentType: Kubernetes
          environment:
            environmentRef: production

Triggers

Artifact Trigger

trigger:
  name: New Artifact Trigger
  identifier: artifact_trigger
  pipelineIdentifier: deploy_pipeline
  source:
    type: Artifact
    spec:
      type: DockerRegistry
      spec:
        connectorRef: docker_connector
        imagePath: myorg/myapp
        tag: <+trigger.artifact.build>

Webhook Trigger

trigger:
  name: GitHub Webhook
  identifier: github_webhook
  pipelineIdentifier: deploy_pipeline
  source:
    type: Webhook
    spec:
      type: Github
      spec:
        type: Push
        spec:
          connectorRef: github_connector
          autoAbortPreviousExecutions: true
          payloadConditions:
            - key: targetBranch
              operator: Equals
              value: main

Scheduled Trigger

trigger:
  name: Nightly Deploy
  identifier: nightly_deploy
  pipelineIdentifier: deploy_pipeline
  source:
    type: Scheduled
    spec:
      type: Cron
      spec:
        expression: "0 2 * * *"  # 2 AM daily
        timezone: America/Los_Angeles

CD Expressions

ExpressionDescription
<+service.name>Service name
<+service.identifier>Service identifier
<+env.name>Environment name
<+env.identifier>Environment identifier
<+env.type>Environment type
<+infra.name>Infrastructure name
<+infra.connectorRef>Infrastructure connector
<+infra.namespace>Kubernetes namespace
<+artifact.image>Full artifact image
<+artifact.tag>Artifact tag
<+artifact.imagePath>Artifact image path
<+pipeline.stages.STAGE.output.VAR>Stage output variable

API Operations

Execute Deployment

curl -X POST "https://app.harness.io/pipeline/api/pipeline/execute/${PIPELINE_ID}?accountIdentifier=${ACCOUNT}&orgIdentifier=${ORG}&projectIdentifier=${PROJECT}" \
  -H "x-api-key: ${API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "runtimeInputYaml": "pipeline:\n  stages:\n    - stage:\n        identifier: deploy\n        spec:\n          serviceConfig:\n            serviceRef: my_service\n            artifactSource:\n              image: myorg/myapp:v1.2.3"
  }'

Get Deployment Status

curl -X GET "https://app.harness.io/pipeline/api/pipelines/execution/v2/${EXECUTION_ID}?accountIdentifier=${ACCOUNT}&orgIdentifier=${ORG}&projectIdentifier=${PROJECT}" \
  -H "x-api-key: ${API_KEY}"

Trigger Rollback

curl -X PUT "https://app.harness.io/pipeline/api/pipelines/execution/interrupt/${EXECUTION_ID}?accountIdentifier=${ACCOUNT}&orgIdentifier=${ORG}&projectIdentifier=${PROJECT}" \
  -H "x-api-key: ${API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"interruptType": "CUSTOM_FAILURE"}'

Troubleshooting

Common Issues

IssueCauseSolution
Deployment timeoutResource limitsIncrease step timeout
Image pull failedAuth issueVerify connector credentials
Namespace not foundInfrastructure issueCheck infrastructure definition
Manifest errorInvalid YAMLValidate manifests locally
Approval timeoutNo approver actionReview approval workflow
Rollback failedMissing rollback stepsAdd rollback configuration

Debug Steps

- step:
    name: Debug Info
    identifier: debug
    type: ShellScript
    spec:
      shell: Bash
      source:
        type: Inline
        spec:
          script: |
            echo "=== Deployment Debug ==="
            echo "Service: <+service.name>"
            echo "Environment: <+env.name>"
            echo "Artifact: <+artifact.image>:<+artifact.tag>"
            echo "Namespace: <+infra.namespace>"
            kubectl get pods -n <+infra.namespace>
            kubectl get events -n <+infra.namespace> --sort-by='.lastTimestamp'

Best Practices

  1. Use service overrides for environment-specific configurations
  2. Implement approval gates for production deployments
  3. Configure rollback strategies for all deployment types
  4. Use GitOps for declarative deployments
  5. Implement deployment verification with CV or custom health checks
  6. Tag resources for cost tracking and governance
  7. Use variables for reusable pipeline configurations
  8. Implement failure strategies at stage and step levels

Related Documentation