CircleCI’s Helm Orb lets you deploy to Kubernetes without writing a single line of Helm CLI code yourself.

Let’s see it in action. Imagine you have a simple Nginx deployment and service configuration in a k8s directory within your project:

# k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

---
# k8s/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: LoadBalancer

Now, you want to deploy this to your Kubernetes cluster whenever you push a change to your main branch. Here’s how your CircleCI configuration (.circleci/config.yml) would look using the Helm Orb:

version: 2.1

orbs:
  helm: circleci/helm@1.5.0 # Use a specific version

jobs:
  deploy-to-k8s:
    docker:
      - image: cimg/base:stable # A basic image with necessary tools
    steps:
      - checkout
      - helm/install-helm # Installs Helm CLI
      - helm/apply: # This is the core command
          kubeconfig: << pipeline.parameters.kubeconfig-value >> # Your Kubeconfig
          context: << pipeline.parameters.kube-context-value >> # Your Kube context
          namespace: default # The Kubernetes namespace to deploy to
          chart-path: k8s # The directory containing your Kubernetes manifests

workflows:
  version: 2
  deploy:
    jobs:
      - deploy-to-k8s:
          filters:
            branches:
              only: main # Only run on pushes to the main branch

parameters: # Define pipeline parameters for sensitive information
  kubeconfig-value:
    type: env_var_name
    default: KUBECONFIG_VALUE
  kube-context-value:
    type: env_var_name
    default: KUBECONTEXT_VALUE

In this setup:

  • We declare the circleci/helm orb.
  • The deploy-to-k8s job uses a base Docker image that has Helm pre-installed or can easily install it.
  • helm/install-helm ensures the Helm binary is available in the job’s environment.
  • The helm/apply command is the magic. It takes your kubeconfig (which you’d store as an environment variable in CircleCI project settings, e.g., KUBECONFIG_VALUE), the desired context within that config, the namespace to deploy to, and the chart-path.
  • Crucially, chart-path: k8s tells the orb to treat the k8s directory as a Helm chart, even if it doesn’t have a Chart.yaml file. It will apply all YAML manifests found within that directory.
  • The workflow is configured to only run this job when changes are pushed to the main branch.
  • Pipeline parameters are used to inject sensitive kubeconfig and context values securely.

When this job runs, CircleCI will:

  1. Check out your code.
  2. Install Helm if it’s not already present.
  3. Execute helm apply -f k8s --kubeconfig $KUBECONFIG_VALUE --context $KUBECONTEXT_VALUE --namespace default. The helm apply command, when used with a directory containing Kubernetes manifests, functions similarly to kubectl apply -R -f k8s, ensuring that all resources defined in your YAML files are created or updated in the cluster.

The real power here is that the orb abstracts away the direct calls to kubectl or helm template | kubectl apply. It handles the orchestration, making your CI/CD pipeline cleaner and more focused on the deployment itself.

The helm/apply command, when pointed at a directory of raw Kubernetes manifests, essentially performs a kubectl apply -R -f <chart-path> operation. It iterates through all YAML files in the specified directory and applies them to your cluster, creating or updating resources as needed. This is a simple yet effective way to manage configurations that don’t require the full templating capabilities of Helm charts.

What most people miss is that helm/apply doesn’t require a Chart.yaml file to operate. You can point it directly at a directory containing standard Kubernetes YAML manifests, and it will treat them as a "chart" to be applied. This makes it incredibly versatile for deploying applications that are defined directly in YAML, without the overhead of creating a full Helm chart structure.

After successfully deploying your Nginx service, the next logical step would be to integrate automated testing of your deployed application.

Want structured learning?

Take the full Circleci course →