Native Helm Deployment
Deploy services using Helm directly in Kubernetes without external CI/CD dependencies
Native Helm is an alternative deployment method that runs Helm deployments directly within Kubernetes jobs, eliminating the need for external CI/CD systems. This provides a more self-contained and portable deployment solution.
Native Helm deployment is an opt-in feature that can be enabled globally or per-service.
Overview
When enabled, Native Helm:
- Creates Kubernetes jobs to execute Helm deployments
- Runs in ephemeral namespaces with proper RBAC
- Provides real-time deployment logs via WebSocket
- Handles concurrent deployments automatically
- Supports all standard Helm chart types
Quickstart
Want to try native Helm deployment? Here’s the fastest way to get started:
This configuration:
- Enables native Helm for the
my-apiservice - Uses a local Helm chart from your repository
- Applies values from
./helm/values.yaml - Runs deployment as a Kubernetes job
To enable native Helm for all services at once, see Global Configuration.
Configuration
Enabling Native Helm
There are two ways to enable native Helm deployment:
Per Service Configuration
Enable native Helm for individual services:
Global Configuration
Enable native Helm for all services:
Configuration Precedence
Lifecycle uses a hierarchical configuration system with three levels of precedence:
- helmDefaults - Base defaults for all deployments (database:
global_configtable) - Chart-specific config - Per-chart defaults (database:
global_configtable) - Service YAML config - Service-specific overrides (highest priority)
Service-level configuration always takes precedence over global defaults.
Global Configuration (Database)
Global configurations are stored in the global_config table in the database. Each configuration is stored as a row with:
- key: The configuration name (e.g., ‘helmDefaults’, ‘postgresql’, ‘redis’)
- config: JSON object containing the configuration
helmDefaults Configuration
Stored in database with key helmDefaults:
Field Descriptions:
enabled: Enables default native Helm behavior in global config. Services still typically opt in withdeploymentMethod: "native"or service-level native Helm settings.defaultArgs: Arguments automatically appended to every Helm command (appears before service-specific args)defaultHelmVersion: The Helm version to use when not specified at the service or chart levelimage: Custom runner image for the native Helm jobpostRenderer.enabled: Enables or disables the configured Helm post-rendererpostRenderer.command: Executable passed to Helm with--post-rendererpostRenderer.args: Arguments passed to Helm as repeated--post-renderer-argsflags
Chart-specific Configuration
Example: PostgreSQL configuration stored with key postgresql:
These global configurations are managed by administrators and stored in the database. They provide consistent defaults across all environments and can be overridden at the service level.
Custom Runner Images and Post-Renderers
Native Helm supports two related customization points:
nativeHelm.imagechanges the container image used for the Helm jobnativeHelm.postRendererconfigures Helm’s--post-rendererintegration
This keeps the model aligned with Helm itself: Lifecycle configures the runner image and optionally tells Helm which post-renderer executable to invoke.
Global Defaults Only
Services can then opt into native Helm without repeating the runner image:
Global Custom Image with Post-Renderer
Service-Level Override
Service config can override either the image or the post-renderer settings:
Disable an Inherited Post-Renderer
If a post-renderer is defined globally, a service can explicitly disable it:
Custom runner images should include Helm and any post-renderer binary
referenced by nativeHelm.postRenderer.command. A common pattern is to start
from an existing Helm image and add your post-renderer binary on top.
Repo-local post-renderer commands for public charts are not supported today unless the deployment already clones the repository for another reason. For public charts, prefer a post-renderer binary that already exists in the runner image.
Usage Examples
Quick Experiment: Deploy Jenkins!
Want to see native Helm in action? Let’s deploy everyone’s favorite CI/CD tool - Jenkins! This example shows how easy it is to deploy popular applications using native Helm.
🎉 That’s it! With just a few lines of configuration, you’ll have Jenkins running in your Kubernetes cluster.
To access your Jenkins instance:
- Check the deployment status in your PR comment
- Click the Deploy Logs link to monitor the deployment
- Once deployed, Jenkins will be available at the internal hostname
For more Jenkins configuration options and values, check out the Bitnami Jenkins chart documentation. This same pattern works for any Bitnami chart (PostgreSQL, Redis, MongoDB) or any other public Helm chart!
Basic Service Deployment
PostgreSQL with Overrides
Custom Environment Variables
Lifecycle supports flexible environment variable formatting through the envMapping configuration. This feature allows you to control how environment variables from your service configuration are passed to your Helm chart.
Why envMapping? Different Helm charts expect environment variables in
different formats. Some expect an array of objects with name and value
fields (Kubernetes standard), while others expect a simple key-value map. The
envMapping feature lets you adapt to your chart’s requirements.
Default envMapping Configuration
You can define default envMapping configurations in the global_config database table. These defaults apply to all services using that chart unless overridden at the service level.
Example: Setting defaults for your organization’s chart
With this configuration, any service using the myorg-web-app chart will automatically use array format for environment variables:
Setting envMapping in global_config is particularly useful when: - You have
a standard organizational chart used by many services - You want consistent
environment variable handling across services - You’re migrating multiple
services and want to reduce configuration duplication
Array Format
Best for charts that expect Kubernetes-style env arrays.
This produces the following Helm values:
Your chart’s values.yaml would use it like:
Map Format
Best for charts that expect a simple key-value object.
This produces the following Helm values:
Note: Underscores in environment variable names are converted to double
underscores (__) in map format to avoid Helm parsing issues.
Your chart’s values.yaml would use it like:
Complete Example with Multiple Services
For supported template variables, see the Template Variables guide.
Chart Types
Lifecycle automatically detects and handles three chart types:
| Type | Detection | Features |
|---|---|---|
| ORG_CHART | Matches orgChartName AND has helm.docker | Docker image injection, env var transformation |
| LOCAL | Name is “local” or starts with ”./” or ”../“ | Flexible envMapping support |
| PUBLIC | Everything else | Standard labels and tolerations |
The orgChartName is configured in the database’s global_config table with
key orgChart. This allows organizations to define their standard internal
Helm chart.
Troubleshooting
Deployment Fails with “Another Operation in Progress”
Symptom: Helm reports an existing operation is blocking deployment
Solution: Native Helm automatically handles this by killing existing jobs. If the issue persists:
Environment Variables Not Working
Symptom: Environment variables not passed to the deployment
Common Issues:
envMappingplaced underchartinstead of directly underhelm- Incorrect format specification (array vs map)
- Missing path configuration
Correct Configuration:
Migration Example
Here’s a complete example showing how to migrate from GitHub-type services to Helm-type services:
Before: GitHub-type Services
After: Helm-type Services with Native Deployment
Key Migration Points
- Service Type Change: Changed from
github:tohelm:configuration - Repository Location:
repositoryandbranchNamemove from undergithub:to directly underhelm: - Deployment Method: Added
deploymentMethod: "native"to enable native Helm - Chart Configuration: Added
chart:section with local or public charts - Environment Mapping: Added
envMapping:to control how environment variables are passed - Helm Arguments: Added
args:for Helm command customization - Docker Configuration: Kept existing
docker:config for build process
Note that when converting from GitHub-type to Helm-type services, the
repository and branchName fields move from being nested under github: to
being directly under helm:.
Many configuration options (like Helm version, args, and chart details) can be
defined in the global_config database table, making the service YAML
cleaner. Only override when needed.