harness-expert

Expert knowledge of Harness template types, expression language, pipeline patterns, and deployment strategies.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "harness-expert" with this command: npx skills add lobbi-docs/claude/lobbi-docs-claude-harness-expert

Harness Expert Skill

Expert knowledge of Harness template types, expression language, pipeline patterns, and deployment strategies.

Harness Template Types

  1. Step Templates

Purpose: Reusable step configurations across pipelines

Types:

  • ShellScript - Execute bash/PowerShell scripts

  • Run - Container step with image/command

  • K8sDeploy - Kubernetes deployments

  • Http - HTTP calls/webhooks

  • Approval - Manual approval gates

  • ServiceNow - ServiceNow integration

  • Custom - Custom step plugins

Template Structure:

template: name: Deploy to Kubernetes type: Step spec: type: K8sDeploy spec: service: <+input> environment: <+input> kubernetesCluster: <+input> namespace: <+input> releaseName: <+input> timeout: <+input.deployment_timeout> skipDryRun: false allowNoFilesFound: false delegateSelectors: - <+input.delegate_selector>

Runtime Inputs (Required):

templateInputs: spec: service: serviceRef: <+input.service_name> environment: environmentRef: <+input.environment_name> kubernetesCluster: clusterId: <+input.cluster_id> namespace: <+input.k8s_namespace> releaseName: <+input.release_name>

  1. Stage Templates

Purpose: Reusable stage definitions with multiple steps

Template Structure:

template: name: Deploy Stage Template type: Stage spec: type: Deployment spec: service: serviceRef: <+input.service_ref> infrastructure: infrastructureDefinition: type: <+input.infra_type> # Kubernetes, AWS, GCP, etc. spec: <+input.infra_spec> execution: steps: - step: name: Deploy identifier: deploy type: K8sDeploy spec: service: <+input.service_ref> environment: <+input.environment_ref> - step: name: Verify identifier: verify type: ShellScript spec: script: <+input.verify_script>

  1. Pipeline Templates

Purpose: Full pipeline definitions with approval gates, notifications, conditions

Template Structure:

template: name: Complete CI/CD Pipeline type: Pipeline spec: stages: - stage: name: Build identifier: build type: CI spec: codebase: repoName: <+input.repo_name> branch: <+input.branch> build: type: Docker spec: dockerfile: Dockerfile registryConnector: <+input.registry_connector>

  - stage:
      name: Deploy Dev
      identifier: deploy_dev
      type: Deployment
      spec:
        service:
          serviceRef: &#x3C;+input.service_ref>
        environment:
          environmentRef: dev
        infrastructure:
          infrastructureDefinition:
            type: Kubernetes
            spec:
              clusterId: &#x3C;+input.dev_cluster_id>

  - stage:
      name: Approval
      identifier: approval
      type: Approval
      spec:
        approvalStepType: ShellScript
        script: echo "Deploying to production..."

  - stage:
      name: Deploy Prod
      identifier: deploy_prod
      type: Deployment
      spec:
        service:
          serviceRef: &#x3C;+input.service_ref>
        environment:
          environmentRef: prod
        infrastructure:
          infrastructureDefinition:
            type: Kubernetes
            spec:
              clusterId: &#x3C;+input.prod_cluster_id>

Runtime Inputs (<+input> ) Syntax

Basic Input Declaration

spec: service: serviceRef: <+input> # Required, user must provide timeout: <+input.deployment_timeout> # Optional with variable name replicas: <+input | default(3)> # With default value

Input Types & Examples

String Input: image: <+input> service: <+input.service_name>

Number Input: timeout: <+input.timeout_minutes> replicas: <+input | default(3)>

Boolean Input: skip_tests: <+input | default(false)> enable_monitoring: <+input>

List/Array Input: environments: <+input.env_list> delegate_selectors: <+input.selectors>

Object Input: infrastructure: <+input.infra_spec>

Conditional Inputs

Only required if another input is true

{{#if use_custom_image}} image: <+input.custom_image> {{/if}}

Conditional with expression

<+if> conditions: - key: environment operator: equals value: production then: <+input.prod_cluster> else: <+input.dev_cluster> </+if>

Expression Language Syntax

Pipeline-Level Expressions

Access pipeline metadata

<+pipeline.name> # Pipeline name <+pipeline.identifier> # Pipeline identifier <+pipeline.executionId> # Execution ID <+pipeline.triggeredBy> # Who triggered it <+pipeline.startTs> # Start timestamp <+pipeline.sequenceNumber> # Execution sequence

Stage-Level Expressions

Access stage metadata

<+stage.name> # Stage name <+stage.identifier> # Stage identifier <+stage.status> # Stage status (Success, Failed, etc.) <+stage.type> # Stage type (CI, Deployment, etc.)

Stage variables

<+stage.variables.VARIABLE_NAME> # Stage variable <+stageArtifacts.IMAGE_ID> # Output artifacts

Step-Level Expressions

Access step outputs

<+steps.STEP_ID.output.outputKey> # Step output variable <+steps.build_docker.output.image> # Docker image from build step <+steps.deploy.status> # Step execution status

Example

<+steps.deploy.deploymentStatuses> # Deployment status details

Environment Variables

<+env.JIRA_URL> # Environment variable <+env.DOCKER_REGISTRY> # From infrastructure

Example in script

  • step: type: ShellScript spec: script: | echo "Registry: <+env.DOCKER_REGISTRY>" docker push <+env.DOCKER_REGISTRY>/myapp

Secret References

Retrieve secrets

<+secrets.getValue("my_secret")> # Simple secret <+secrets.getValue("vault://prod/db_pwd")> # Vault path

Example

  • step: type: ShellScript spec: environmentVariables: DB_PASSWORD: <+secrets.getValue("database_password")>

Artifact & Output Expressions

Artifacts from previous stages

<+artifact.image> # Primary artifact <+artifact.imageTag> # Image tag <+artifacts.COLLECTOR.IMAGE_ID> # Named artifact

Example in deploy

  • step: type: K8sDeploy spec: image: <+artifact.image>:<+artifact.imageTag> service: <+input.service_ref>

Pipeline Patterns

Pattern 1: CI/CD Standard

Description: Standard continuous integration and deployment

Flow: Build → Test → Deploy Dev → Approval → Deploy Prod

template: name: Standard CI/CD type: Pipeline spec: stages: # Stage 1: Build - stage: name: Build identifier: build type: CI spec: codebase: repoName: <+input.repo_name> branch: <+input.branch> build: type: Docker spec: dockerfile: Dockerfile registryConnector: <+input.docker_connector> imageName: <+input.image_name> imageTag: <+artifact.imageTag>

  # Stage 2: Test
  - stage:
      name: Test
      identifier: test
      type: CI
      depends:
        on:
          - build
      spec:
        build:
          type: Container
          spec:
            image: &#x3C;+steps.build.output.image>
            command: npm test -- --coverage

  # Stage 3: Deploy Dev
  - stage:
      name: Deploy Dev
      identifier: deploy_dev
      type: Deployment
      depends:
        on:
          - test
      spec:
        service:
          serviceRef: &#x3C;+input.service_ref>
        environment:
          environmentRef: dev
        infrastructure:
          infrastructureDefinition:
            type: Kubernetes
            spec:
              clusterId: &#x3C;+input.dev_cluster>
        execution:
          steps:
            - step:
                type: K8sDeploy
                spec:
                  service: &#x3C;+input.service_ref>
                  image: &#x3C;+artifact.image>

  # Stage 4: Manual Approval
  - stage:
      name: Approval for Production
      identifier: approval
      type: Approval
      depends:
        on:
          - deploy_dev
      spec:
        approvalStepType: Manual
        approvers:
          - &#x3C;+input.approver_group>

  # Stage 5: Deploy Production
  - stage:
      name: Deploy Production
      identifier: deploy_prod
      type: Deployment
      depends:
        on:
          - approval
      spec:
        service:
          serviceRef: &#x3C;+input.service_ref>
        environment:
          environmentRef: prod
        infrastructure:
          infrastructureDefinition:
            type: Kubernetes
            spec:
              clusterId: &#x3C;+input.prod_cluster>
        execution:
          steps:
            - step:
                type: K8sDeploy
                spec:
                  service: &#x3C;+input.service_ref>
                  image: &#x3C;+artifact.image>

Pattern 2: GitOps with ArgoCD

Description: GitOps pattern using Argo CD for deployments

Flow: Build → Push Manifest → Trigger ArgoCD → Verify

template: name: GitOps CI/CD Pipeline type: Pipeline spec: stages: # Stage 1: Build Docker Image - stage: name: Build identifier: build type: CI spec: codebase: repoName: <+input.repo_name> branch: <+input.branch> build: type: Docker spec: dockerfile: Dockerfile registryConnector: <+input.docker_connector> imageName: <+input.image_name>

  # Stage 2: Update Manifest Repository
  - stage:
      name: Update Manifests
      identifier: update_manifests
      type: CI
      depends:
        on:
          - build
      spec:
        steps:
          - step:
              type: Run
              spec:
                container:
                  image: ubuntu:22.04
                  shell: Bash
                script: |
                  git clone &#x3C;+input.manifest_repo> manifests
                  cd manifests
                  sed -i "s|IMAGE_TAG|&#x3C;+artifact.imageTag>|g" k8s/deployment.yaml
                  git add k8s/deployment.yaml
                  git commit -m "Update image to &#x3C;+artifact.imageTag>"
                  git push origin main

  # Stage 3: Trigger ArgoCD Sync
  - stage:
      name: Deploy via ArgoCD
      identifier: deploy_argocd
      type: Deployment
      depends:
        on:
          - update_manifests
      spec:
        steps:
          - step:
              type: Http
              spec:
                url: &#x3C;+input.argocd_api_url>/api/v1/applications/&#x3C;+input.app_name>/sync
                method: Post
                headers:
                  Authorization: Bearer &#x3C;+secrets.getValue("argocd_token")>
                requestBody: |
                  {
                    "syncPolicy": {
                      "syncStrategy": {
                        "argo": {}
                      }
                    }
                  }

  # Stage 4: Verify Deployment
  - stage:
      name: Verify
      identifier: verify
      type: Deployment
      depends:
        on:
          - deploy_argocd
      spec:
        steps:
          - step:
              type: ShellScript
              spec:
                script: |
                  kubectl rollout status deployment/&#x3C;+input.app_name> \
                    -n &#x3C;+input.namespace> \
                    --timeout=5m

Pattern 3: Canary Deployment

Description: Gradual traffic shift with automated verification

Flow: Deploy Canary (5%) → Verify → Increment Traffic (25%) → Verify → Full Deploy

template: name: Canary Deployment Pattern type: Pipeline spec: stages: # Stage 1: Deploy Canary (5% traffic) - stage: name: Deploy Canary identifier: deploy_canary type: Deployment spec: service: serviceRef: <+input.service_ref> environment: environmentRef: prod infrastructure: infrastructureDefinition: type: Kubernetes spec: clusterId: <+input.prod_cluster> execution: steps: - step: type: K8sDeploy spec: canaryStrategy: enabled: true canaryPercentage: 5 service: <+input.service_ref> image: <+artifact.image>

  # Stage 2: Verify Canary Metrics
  - stage:
      name: Verify Canary
      identifier: verify_canary
      type: Deployment
      depends:
        on:
          - deploy_canary
      spec:
        steps:
          - step:
              type: ShellScript
              spec:
                script: |
                  # Check error rate, latency, etc.
                  kubectl logs -l version=canary -n &#x3C;+input.namespace> \
                    --since=10m | grep ERROR | wc -l > /tmp/errors
                  ERRORS=$(cat /tmp/errors)
                  if [ $ERRORS -gt &#x3C;+input.error_threshold> ]; then
                    exit 1
                  fi

  # Stage 3: Increment Traffic (25%)
  - stage:
      name: Increment Traffic
      identifier: increment_traffic
      type: Deployment
      depends:
        on:
          - verify_canary
      spec:
        steps:
          - step:
              type: ShellScript
              spec:
                script: |
                  kubectl patch vs &#x3C;+input.service_ref> -n &#x3C;+input.namespace> \
                    -p '{"spec":{"hosts":[{"name":"*","http":[{"match":[{"uri":{"regex":".*"}}],"route":[{"destination":{"host":"&#x3C;+input.service_ref>","subset":"canary"},"weight":25}]}]}]}}'

  # Stage 4: Verify Again
  - stage:
      name: Verify Increment
      identifier: verify_increment
      type: Deployment
      depends:
        on:
          - increment_traffic
      spec:
        steps:
          - step:
              type: ShellScript
              spec:
                script: |
                  sleep 300  # Wait 5 minutes
                  # Same verification logic

  # Stage 5: Full Deployment
  - stage:
      name: Deploy Full
      identifier: deploy_full
      type: Deployment
      depends:
        on:
          - verify_increment
      spec:
        steps:
          - step:
              type: K8sDeploy
              spec:
                service: &#x3C;+input.service_ref>
                image: &#x3C;+artifact.image>
                canaryStrategy:
                  enabled: true
                  canaryPercentage: 100

Pattern 4: Blue-Green Deployment

Description: Two identical production environments with instant switching

Flow: Build → Deploy to Green (inactive) → Verify → Switch Traffic → Cleanup Blue

template: name: Blue-Green Deployment Pattern type: Pipeline spec: variables: - name: active_color type: String default: blue - name: inactive_color type: String default: green

stages:
  # Stage 1: Deploy to Inactive Environment
  - stage:
      name: Deploy to Inactive
      identifier: deploy_inactive
      type: Deployment
      spec:
        service:
          serviceRef: &#x3C;+input.service_ref>
        environment:
          environmentRef: &#x3C;+pipeline.variables.inactive_color>
        infrastructure:
          infrastructureDefinition:
            type: Kubernetes
            spec:
              clusterId: &#x3C;+input.prod_cluster>
        execution:
          steps:
            - step:
                type: K8sDeploy
                spec:
                  service: &#x3C;+input.service_ref>
                  image: &#x3C;+artifact.image>

  # Stage 2: Run Smoke Tests
  - stage:
      name: Smoke Tests
      identifier: smoke_tests
      type: CI
      depends:
        on:
          - deploy_inactive
      spec:
        steps:
          - step:
              type: Run
              spec:
                container:
                  image: postman/newman
                  shell: Bash
                script: |
                  newman run tests/smoke-collection.json \
                    --environment env-&#x3C;+pipeline.variables.inactive_color>.json \
                    --reporters cli,json

  # Stage 3: Manual Approval for Switch
  - stage:
      name: Approve Traffic Switch
      identifier: approve_switch
      type: Approval
      depends:
        on:
          - smoke_tests
      spec:
        approvalStepType: Manual
        approvers:
          - &#x3C;+input.approver_group>

  # Stage 4: Switch Traffic
  - stage:
      name: Switch Traffic
      identifier: switch_traffic
      type: Deployment
      depends:
        on:
          - approve_switch
      spec:
        steps:
          - step:
              type: ShellScript
              spec:
                script: |
                  # Switch load balancer/service to point to inactive environment
                  kubectl patch service &#x3C;+input.service_ref> \
                    -n production \
                    -p '{"spec":{"selector":{"version":"&#x3C;+pipeline.variables.inactive_color>"}}}'

  # Stage 5: Verify Active Environment
  - stage:
      name: Verify Active
      identifier: verify_active
      type: Deployment
      depends:
        on:
          - switch_traffic
      spec:
        steps:
          - step:
              type: ShellScript
              spec:
                script: |
                  for i in {1..30}; do
                    STATUS=$(curl -s -o /dev/null -w "%{http_code}" &#x3C;+input.prod_url>/health)
                    if [ $STATUS -eq 200 ]; then
                      echo "Health check passed"
                      exit 0
                    fi
                    sleep 10
                  done
                  exit 1

  # Stage 6: Cleanup Old Environment
  - stage:
      name: Cleanup
      identifier: cleanup
      type: Deployment
      depends:
        on:
          - verify_active
      spec:
        steps:
          - step:
              type: ShellScript
              spec:
                script: |
                  kubectl scale deployment &#x3C;+input.service_ref>-&#x3C;+pipeline.variables.active_color> \
                    -n production \
                    --replicas=0

Template Versioning Best Practices

Version Format

MAJOR.MINOR.PATCH

  • MAJOR: Breaking changes (input names change, outputs change)
  • MINOR: New optional inputs or non-breaking changes
  • PATCH: Bug fixes, documentation updates

Version Declaration

template: name: Deploy Service identifier: deploy_service versionLabel: "2.1.0" spec: # Template specification

Using Versioned Templates

Always use specific version in production

stages:

  • stage: template: templateRef: deploy_service versionLabel: "2.1.0" # Explicit version templateInputs: spec: service: <+input.service_ref>

Changelog Maintenance

Version 2.1.0 (2024-01-15)

  • Added: Support for custom health checks
  • Added: Optional monitoring setup
  • Improved: Error messages for common issues
  • Fixed: Timeout handling in K8s deployments

Version 2.0.0 (2024-01-01) - BREAKING

  • Changed: Input name from 'cluster' to 'clusterId'
  • Changed: Stage type from 'Deploy' to 'Deployment'
  • Removed: Legacy inline script support

Version 1.0.0 (2023-12-01)

  • Initial release

Common Step Configurations

K8s Deployment Step

  • step: name: Deploy to Kubernetes identifier: k8s_deploy type: K8sDeploy spec: service: <+input.service_ref> environment: <+input.environment_ref> kubernetesCluster: clusterId: <+input.cluster_id> namespace: <+input.namespace> releaseName: <+input.release_name> timeout: 10m skipDryRun: false allowNoFilesFound: false delegateSelectors: - <+input.delegate_selector>

Container Step (Docker/Podman)

  • step: name: Run Docker Step identifier: docker_step type: Run spec: container: image: <+input.image> shell: Bash runAsUser: <+input.user> script: | #!/bin/bash set -e echo "Running test suite..." npm test -- --coverage echo "Test passed!" envVariables: TEST_ENV: <+input.environment> API_URL: <+env.API_URL> outputVariables: - name: test_result value: $(cat test-results.json)

HTTP Step

  • step: name: Notify Slack identifier: notify_slack type: Http spec: url: <+input.slack_webhook> method: Post headers: Content-Type: application/json requestBody: | { "text": "Deployment to <+input.environment> completed!", "attachments": [ { "text": "Version: <+artifact.imageTag>" } ] }

Approval Step

  • step: name: Manual Approval identifier: approval type: Approval spec: approvalMessage: Deploy to production? approvers: - <+input.approver_group> approvalTimeout: 1d autoRejectIfNoActivity: true isAutoRejectAfterOverride: true

Related Documentation

  • Harness Docs

  • Pipeline Templates

  • Expression Language

  • Deployment Strategies

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Research

deep-analysis

No summary provided by upstream source.

Repository SourceNeeds Review
Research

deep-research

No summary provided by upstream source.

Repository SourceNeeds Review
Research

web-research

No summary provided by upstream source.

Repository SourceNeeds Review