Automating with Helm in CI/CD
1. Installing Helm in Pipeline
| Platform | Installation Method | Command | Notes |
|---|---|---|---|
| Linux (x86_64) | Download binary | curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 && chmod 700 get_helm.sh && ./get_helm.sh |
Installs latest stable version |
| macOS | Homebrew | brew install helm |
Installs latest stable version |
| Windows | Chocolatey | choco install kubernetes-helm |
Installs latest stable version |
| Windows | PowerShell | iwr -useb https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | iex |
Installs latest stable version |
| Docker | Container | docker run --rm -it alpine/helm:latest version |
Useful for CI/CD environments |
Example: Installing Helm in a GitHub Actions Workflow
name: Deploy with Helm
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Install Helm
run: |
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh
- name: Deploy to Kubernetes
run: helm upgrade --install my-app ./helm-chart
2. Authenticating to Kubernetes
| Method | Description | Configuration | Notes |
|---|---|---|---|
| kubeconfig | Uses kubeconfig file for authentication | helm install --kubeconfig /path/to/kubeconfig |
Standard Kubernetes authentication method |
| service-account | Uses Kubernetes service account token | helm install --set serviceAccount.name=helm |
Recommended for CI/CD environments |
| client-certificate | Uses client certificate and key | helm install --set tls.clientCert=/cert.pem --set tls.clientKey=/key.pem |
For mutual TLS authentication |
| bearer-token | Uses bearer token for API access | helm install --set bearerToken=token123 |
Not recommended for CI/CD due to security concerns |
Example: Using Service Account in CI/CD
apiVersion: v1
kind: ServiceAccount
metadata:
name: helm-deployer
namespace: production
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: helm-deployer-role
namespace: production
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: helm-deployer-binding
namespace: production
subjects:
- kind: ServiceAccount
name: helm-deployer
apiGroup: ""
roleRef:
kind: Role
name: helm-deployer-role
apiGroup: ""
Note: Ensure the service account has appropriate RBAC permissions for Helm operations.
Warning: Never store kubeconfig or tokens in plain text in CI/CD pipelines.
3. Running Helm Lint
| Option | Values | Notes |
|---|---|---|
| --strict | true |
Fail on warnings during linting |
| --set | key=value |
Set values for linting |
| --values | file.yaml |
Specify values file for linting |
Note: Helm lint checks for syntax errors and common issues in chart templates.
Warning: Linting does not validate actual deployment, only chart structure and templates.
4. Performing Dry Run
| Flag | Description | Default |
|---|---|---|
| --dry-run | Simulates the installation without actually deploying resources | false |
| --debug | Enables debug output including rendered templates | false |
Note: Dry run does not validate chart dependencies or perform any actual deployment.
Warning: Use
--dry-run in combination with --debug to inspect rendered templates before applying.5. Deploying Charts
| Property | Value | Description |
|---|---|---|
| helm upgrade | helm upgrade [RELEASE_NAME] [CHART_PATH] |
Upgrade a release with the specified chart |
| helm install | helm install [RELEASE_NAME] [CHART_PATH] |
Install a new release from the specified chart |
| --set | --set key1=value1,key2=value2 |
Set values during installation or upgrade |
| --values | --values values.yaml |
Specify a YAML file with configuration values |
| --namespace | --namespace my-namespace |
Deploy chart in a specific namespace |
| --wait | --wait |
Wait for all resources to be ready before marking the release as successful |
Example: Deploying a Chart with Values
helm install my-app ./my-chart --values config.yaml --namespace production --wait
Example: Upgrading a Release with Set Values
helm upgrade my-app ./my-chart --set image.tag=v2.0 --set service.port=8080
Note: The
--wait flag ensures that the deployment is fully ready before marking it as successful, which is useful in CI/CD pipelines.
6. Running Chart Tests
| Command | Description | Notes |
|---|---|---|
| helm test | Run tests defined in a chart | Tests are defined in templates/tests/ |
| helm test <release-name> | Run tests for a specific release | Requires the release to be installed |
Note: Tests must be defined in
templates/tests/ directory of the chart.
Warning: Helm tests are not designed to run in CI/CD pipelines without proper setup and cleanup.
7. Rolling Back on Failure
| Action | Description | Command | Notes |
|---|---|---|---|
| Rollback to previous revision | Revert to the last successfully deployed revision | helm rollback <release-name> |
Rolls back to the previous revision by default |
| Rollback to specific revision | Revert to a specific revision number | helm rollback <release-name> <revision> |
Use helm history to find revision numbers |
| Rollback with timeout | Set a timeout for rollback operation | helm rollback <release-name> --timeout 5m |
Prevents long-running rollbacks from hanging |
| Rollback with no-hooks | Prevent hooks from running during rollback | helm rollback <release-name> --no-hooks |
Useful for avoiding side effects from hooks |
| Rollback with dry-run | Simulate rollback without applying changes | helm rollback <release-name> --dry-run |
Useful for testing rollback behavior before actual execution |
Note: Rollbacks are not supported for
helm install operations that failed during the initial deployment. In such cases, you must manually clean up and redeploy.
Warning: Rollbacks can cause data loss or inconsistencies if the rollback target has incompatible resource definitions (e.g., changed CRD versions). Always verify the rollback outcome before proceeding.
8. Publishing Charts
| Option | Values | Notes |
|---|---|---|
| helm package | helm package <chart-directory> |
Creates a .tgz archive of the chart |
| helm repo add | helm repo add <repo-name> <repo-url> |
Adds a new repository to local Helm configuration |
| helm repo update | helm repo update |
Updates the local cache of repository information |
| helm push | helm push <chart-path> <repo-url> |
Pushes a chart to a remote repository (requires Helm 3.8+) |
Example: Publishing a Chart to Artifact Hub
helm package myapp/
helm repo add artifact-hub https://artifacthub.io
helm push myapp-1.0.0.tgz artifact-hub
Note: Ensure chart metadata includes valid
name, version, and appVersion fields before publishing.
Warning: Chart versions must be unique within a repository; reusing a version will overwrite the existing chart.
9. Versioning with CI Variables
| Variable | Usage | Description |
|---|---|---|
| CI_COMMIT_TAG | helm upgrade --set image.tag=${CI_COMMIT_TAG} my-release ./my-chart |
Tag from GitLab CI/CD pipeline, used for image versioning |
| CI_COMMIT_SHORT_SHA | helm install my-release ./my-chart --set image.tag=${CI_COMMIT_SHORT_SHA} |
Short Git commit SHA, useful for dev deployments |
| CI_PIPELINE_ID | helm template ./my-chart --set releaseId=${CI_PIPELINE_ID} |
Unique identifier for the CI pipeline run |
Example: Using CI Variables in Helm Values
image:
repository: my-app
tag: "${CI_COMMIT_TAG}"
pullPolicy: IfNotPresent
service:
port: 8080
type: ClusterIP
Note: Ensure that CI variables are properly escaped in YAML files to avoid parsing errors.
10. Using GitOps Workflows
Example: GitOps with ArgoCD and Helm
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-helm-app
spec:
project: default
source:
repoURL: https://github.com/myorg/my-repo.git
targetRevision: HEAD
path: helm-charts/my-app
helm:
valueFiles:
- values-production.yaml
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
| Component | Description | Notes |
|---|---|---|
| Application.spec.source.repoURL | https://github.com/myorg/my-repo.git |
Git repository containing Helm charts |
| Application.spec.source.path | helm-charts/my-app |
Path to the Helm chart in the repo |
| Application.spec.source.helm.valueFiles | values-production.yaml |
Override values file for environment |
| Application.spec.syncPolicy | automated |
Automatically sync changes from Git |
GitOps Workflow Benefits
- Version-controlled deployments
- Automated rollback on failure
- Centralized configuration management
- Compliance and audit trail
GitOps vs Traditional CI/CD
- GitOps: Declarative, infrastructure as code
- Traditional CI/CD: Imperative, pipeline-driven
Note: GitOps requires a Git repository as the source of truth for all infrastructure and application configurations.
11. Implementing Blue-Green Deployments
Example: Blue-Green Deployment with Helm
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-blue
spec:
replicas: 3
selector:
matchLabels:
app: myapp
version: blue
template:
metadata:
labels:
app: myapp
version: blue
spec:
containers:
- name: app
image: myapp:v1.2.0
ports:
- containerPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-green
spec:
replicas: 0
selector:
matchLabels:
app: myapp
version: green
template:
metadata:
labels:
app: myapp
version: green
spec:
containers:
- name: app
image: myapp:v1.3.0
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: app-service
spec:
selector:
app: myapp
version: blue
ports:
- port: 80
targetPort: 8080
| Component | Description | Notes |
|---|---|---|
| Deployment (blue) | app-blue |
Active deployment with v1.2.0 image |
| Deployment (green) | app-green |
Inactive deployment with v1.3.0 image |
| Service Selector | version: blue |
Routes traffic to blue deployment |
Deployment Workflow
- Deploy
v1.3.0to green deployment - Run tests on green deployment
- Update service selector to
version: green - Scale down blue deployment to 0 replicas
Note: Blue-green deployments require two separate deployments and a service that can be switched between them.