For the complete documentation index, see llms.txt. This page is also available as Markdown.

Use Harness expressions in GitOps manifests

Inject Harness service variables, environment variables, and secrets into Argo CD manifests at manifest generation time.

Use the Harness GitOps plugin to resolve Harness expressions in Kubernetes manifests during Argo CD's manifest generation phase. This lets you inject dynamic values from Harness services and environments into your manifests before Argo CD applies them to the cluster.

What you will learn from this topic

Secrets and security

This topic covers expressions and tool detection. Go to Secret injection in GitOps applications for Vault and Secret Manager integration and the security model.


Before you begin

Before using Harness expressions in GitOps manifests, ensure you have:

  • GitOps Agent: Agent version v0.105.x or later installed and running. Go to Install a Harness GitOps Agent for installation steps.

  • Agent installer helper: gitops-agent-installer-helper version v0.0.16 or later (v0.0.18 or later is required for Kustomize support).

  • Harness service: A GitOps service configured with variables. Go to GitOps services to create and configure services.

  • Harness environment: An environment configured with variables and linked to your service. Go to Environments overview to configure environments and variables.


Configure the Harness Argo CD plugin

Do this once when setting up the agent. If the plugin is already enabled on your agent, skip to Connect an application to the plugin.

For new Agent installations: Select the Enable ArgoCD Harness Plugin (Required for Harness expression resolution) checkbox during GitOps agent installation to use this feature. No additional configuration is needed.

Enable ArgoCD Harness Plugin checkbox in GitOps Agent installation wizard

For existing Agent installations (BYOA or Harness-installed Argo): The Enable ArgoCD Harness Plugin (Required for Harness expression resolution) checkbox cannot be changed after the initial installation. You must configure the Harness Argo CD plugin manually. Go to Enable the plugin on an existing agent or BYOA for instructions.

Once enabled, connect each Application to the plugin and use expressions in your manifests:

Step 1. Connect the Application to the plugin

Set the plugin name on the Application:

Or add .harness.yaml to the Application's source directory. Go to Connect an application to the plugin for details on both methods.

Step 2. Use expressions in your manifests

Expressions resolve at manifest generation time. Sync (or let auto-sync trigger) and the deployed manifest contains the resolved values.

Limitations

The following limitations apply when you use the Harness plugin:

Limitation
Details

Kustomize secretGenerator

Secret resolution inside secretGenerator-produced Secret objects is unverified; use plain Secret manifests instead until confirmed.

Application source type shows as Plugin

Argo CD shows source type as Plugin instead of Helm/Directory. Path listing in UI will not work; specify paths manually.

HELM_ARGS

Shell-injection risk; go to HELM_ARGS environment variable for the warning.


Connect an application to the plugin

There are two ways to connect an Application to the plugin. Use either method:

Method
How

Explicit plugin name

Set spec.source.plugin.name: argocd-harness-plugin on the Application

File-based activation

Add .harness.yaml to the Application's source directory

Explicit plugin name:

File-based activation: commit .harness.yaml to the application's source directory:

In the example below, the Argo CD Application's spec.source.path is helm-guestbook. The .harness.yaml file is committed inside that directory, alongside Chart.yaml and values.yaml.

.harness.yaml committed inside the helm-guestbook source directory on GitHub

Custom activation conditions (optional, advanced)

Not required for most setups. Use this only if neither the explicit plugin name nor the .harness.yaml marker fits your workflow, for example, if you want to use a different filename, or check for multiple possible markers.

The plugin checks for .harness.yaml using a shell command in the ConfigManagementPlugin spec. You can replace that command with any shell expression that exits 0 for applications the plugin should process and non-zero for those it should not. The command runs inside the Application's source directory (spec.source.path).

To customize, edit the discover.find.command in the plugin ConfigMap directly. Go to Enable the plugin on an existing agent or BYOA for the ConfigMap structure.

Or check for a specific key inside the file:

The built-in default (test -f .harness.yaml) is sufficient for almost all cases. Custom conditions are a BYOA or Helm-managed install concern; Harness-provisioned agents manage this ConfigMap automatically.


Manifest tool selection

No configuration needed for most applications. The plugin detects Helm, Kustomize, or plain manifests automatically. Read this section only if auto-detection is picking the wrong tool for your application.

Tool selection at generation time

Once the plugin is processing an Application, it auto-detects the manifest tool by inspecting the source directory. For most applications this requires no configuration. The following table lists the detection rules:

Condition
Tool used

kustomization.yaml, kustomization.yml, or Kustomization exists

kustomize build .

Chart.yaml or values.yaml exists

helm template

None of the above

Plain manifests (native)

Expressions are resolved on the tool's output, after Helm or Kustomize has already rendered the manifests.

If auto-detection picks the wrong tool, you can override it. Go to Overriding the manifest tool.

Plain manifests

No Chart.yaml or kustomization.yaml: just raw manifests. No extra configuration needed:

Helm

Plugin runs helm template and resolves expressions in the output. Helm subchart dependencies (helm dependency build) run automatically; no need to vendor charts/:

Kustomize

Plugin runs kustomize build . and resolves expressions in the output. Expressions can appear in any resource Kustomize renders, including patches:

Overriding the manifest tool

If auto-detection picks the wrong tool, add a tool: key to .harness.yaml:


Expression reference

All expressions resolve at manifest generation time (pre-deployment, not runtime).

Expression types

The following expressions are available in GitOps manifests:

Expression
Source
Example

<+serviceVariables.name>

Service-level variables

<+serviceVariables.replicas>

<+env.variables.name>

Environment-level variables

<+env.variables.logLevel>

<+env.name>

Environment display name

production

<+env.identifier>

Environment identifier

prod

<+env.type>

Environment type

Production or PreProduction

<+env.description>

Environment description

<+variable.account.name>

Account-scope fixed variable

<+variable.account.companyId>

<+variable.org.name>

Org-scope fixed variable

<+variable.org.defaultRegion>

<+variable.name>

Project-scope fixed variable

<+variable.projectCode>

<+secrets.getValue("ref")>

Secret (direct reference)

<+secrets.getValue("vault_secret")>

<+serviceVariables.name> (Secret type)

Secret via service variable

resolves to <+secrets.getValue(...)>

Define variables

  • Service variables: Deployments -> Services -> select the service -> Configuration -> Variables

  • Environment variables: Deployments -> Environments -> select the environment -> Configuration -> Variables

  • Fixed variables: Account, Org, or Project Settings -> Variables

Override priority

When the same variable name exists at multiple levels, the highest-priority override wins:

The following table describes each override type:

Override type
How to configure
Scope

ENV_SERVICE

Environment -> Service Overrides -> select service

Overrides a service variable for a specific service and environment pair

ENV_GLOBAL

Environment -> Configuration -> Variables

Overrides an environment variable for all services in that environment

Secret variables

Variables defined as type Secret in Harness go through two-stage resolution:

  1. Manifest generation: <+serviceVariables.dbPassword> resolves to <+secrets.getValue('account.prodDbPassword')>.

  2. Deployment time: The actual secret value is injected into the cluster.

Secret expressions (<+secrets.getValue()>) are only resolved when they appear inside a kind: Secret resource.

Complete example

GitOps expressions vs pipeline expressions

GitOps expressions are a subset of Harness expressions: they only have access to service and environment context, not pipeline runtime context.

Exception for PR pipelines

When syncing manifests within PR Pipelines (for example, using the GitOps Sync step), GitOps expressions can access pipeline runtime context. This allows you to reference pipeline variables, execution details, and other pipeline-level expressions during PR Pipeline execution.

The following table compares GitOps expressions and pipeline expressions:

GitOps expressions
Pipeline expressions

When resolved

Manifest generation (pre-deploy)

Pipeline runtime

Context

Service + environment + metadata

Full pipeline (artifact.*, infra.*, stage.*, etc.)

Not available

pipeline.*, stage.*, artifact.*, infra.*

Use GitOps expressions when the value is known at manifest generation time and tied to service or environment config. Use pipeline expressions for artifact versions, build numbers, or step outputs.


Enable the plugin on an existing agent or BYOA

The Enable ArgoCD Harness Plugin checkbox can only be set at initial Agent installation. Use one of these patch paths if your agent is already installed.

Helm chart installations

  1. Set in values.yaml:

  2. Upgrade the release:

  3. Verify Kustomize is available (requires sidecar image ≥ v0.0.18):

    If kustomize version returns "command not found," bump the sidecar image tag above v0.0.18 and re-apply.

Plain Kubernetes manifest installations

  1. Apply the plugin ConfigMap:

  2. Patch the argocd-repo-server Deployment to add the sidecar (skip if already present):

  3. Verify:

Upgrade from an older plugin install

If you already have an argocd-harness-plugin ConfigMap from a previous install, re-applying the ConfigMap in step 1 is sufficient; you do not need to re-patch the Deployment. Just verify the sidecar image tag is ≥ v0.0.18.

HELM_ARGS environment variable

The plugin passes ${ARGOCD_ENV_HELM_ARGS} directly to helm template:


Troubleshooting

Expression appears literally in the deployed manifest

The expression was not resolved: it shows as <+serviceVariables.replicas> instead of 3.

Try first: Hard-refresh the Argo CD application to invalidate the manifest cache.

Then check:

  1. Variable exists? Verify the variable name and scope in Harness UI (exact match, case-sensitive).

  2. Plugin enabled? Check that spec.source.plugin.name: argocd-harness-plugin is set on the Application.

  3. Typo? Check for extra spaces or incorrect syntax; expressions are <+serviceVariables.name> not <+ serviceVariables.name>.

Kustomize: "command not found"

The sidecar image predates Kustomize support. Bump the image tag to ≥ v0.0.18 and re-apply. Go to Enable the plugin on an existing agent or BYOA.

Override not taking effect
  1. Wrong scope: Service variables must be overridden at ENV_SERVICE level; environment variables at ENV_GLOBAL. You cannot override a service variable using ENV_GLOBAL.

  2. Not saved? Verify the override is saved and the correct service+environment combination is selected.

  3. Name mismatch? Override variable name must match exactly (case-sensitive).

Numeric value rendered as string

Define the variable as type Number (not String) in Harness:

Harness expressions stopped resolving after an agent upgrade or recreation

Symptom: An application that previously had Harness expressions resolved in its manifests no longer resolves them after you upgraded or recreated the agent. The expressions appear literally in the deployed manifests (for example, <+serviceVariables.replicas> instead of 3).

Cause: If the application did not have spec.source.plugin.name: argocd-harness-plugin set, expression resolution depends on .harness.yaml being present in the application's source directory. If that file is absent, the Harness plugin does not process the application's manifests.

Fix:

Choose one of the following options:

  • Set spec.source.plugin.name: argocd-harness-plugin on the Application. Argo CD routes the Application directly to the plugin regardless of what files are in the repo.

  • Commit .harness.yaml to the application's source path. The file must be inside spec.source.path, not the repo root. Go to Connect an application to the plugin for details.

Secret not resolving
  1. Variable must be type Secret (not String) to trigger two-stage resolution.

  2. Secret must exist in Harness Secrets Manager before being referenced.

  3. Check secret reference format: account.secretName or org.secretName.


Next steps

Last updated

Was this helpful?