The Helmfile setup follows a structured directory layout to manage environments, releases, and configurations efficiently:
project-root/
│── charts.yaml # Defines available Helm charts and repositories
│── helmfile.yaml.gotmpl # Main Helmfile configuration
│── environments/ # Contains per-environment configurations
│ │── production/ # Example environment folder
│ │ │── cluster.yaml # Defines environment-specific settings and enabled releases
│ │ │── values/ # Stores custom values per release
│ │ │── secrets/ # Contains encrypted secrets managed by SOPS
This structure helps maintain modularity and separation of concerns, making it easier to manage multiple environments.
This Helmfile template provides a structured approach for managing Kubernetes cluster deployments across multiple environments. By leveraging Helmfile's templating capabilities, this setup ensures:
- Modular release management: Centralized
charts.yamlfor defining available Helm charts and their repositories, while each environment defines its enabled releases incluster.yamlunder the keyreleases. - Environment-specific configurations: Dynamically reads
cluster.yamlper environment. - Flexible values management: Supports custom
values/and encryptedsecrets/per environment.
This document explains how to use this Helmfile setup to add new releases, enable them for specific environments, and manage environment-specific configurations.
A release represents a Helm chart deployment that can be enabled per environment.
-
Define the release in
charts.yamlAdd a new entry under thereleasessection incharts.yaml:releases: my-app: namespace: my-namespace chart: my-repo/my-app
namespace: The Kubernetes namespace where the application should be deployed. This can be omitted and left to be environment specific.chart: The Helm chart repository and name. If the repository doesn't exist, it needs to be added first.
-
Enable the release for a specific environment Edit
environments/<environment>/cluster.yamland add the release underreleases:environment: kubeContext: my-cluster releases: my-app:
- One can define additional per release configuration for environment-specific overrides. For example, adding hooks or dependencies on other releases. Refer to helmfile documentation for release spec definition.
- This enables the release only for this environment.
-
(Optional) Add custom values and secrets
- To override Helm values per environment, create a file:
touch environments/<environment>/values/my-app.yaml.gotmpl
- To manage secrets securely with SOPS, create:
And encrypt it using SOPS:
touch environments/<environment>/secrets/my-app.yaml
sops -e -i environments/<environment>/secrets/my-app.yaml
- To override Helm values per environment, create a file:
Once a release is added and enabled for an environment, you can deploy it using Helmfile. Ensure that you are executing the command from the project root directory where helmfile.yaml.gotmpl is located.
helmfile -e <environment> apply- This applies the configurations for the specified environment.
- Helmfile will:
- Load the appropriate
cluster.yaml - Merge values from
values/andsecrets/ - Deploy the enabled releases
- Load the appropriate
To check what changes will be applied:
helmfile -e <environment> diffThis Helmfile-based deployment strategy aligns well with GitOps principles by ensuring that the Kubernetes cluster state is managed declaratively and reconciled automatically. The key components of GitOps implementation in this setup are:
- All Kubernetes resources, including Helm releases and configurations, are defined in YAML files and stored in Git.
charts.yamlacts as the central source of truth for Helm chart versions and configurations.- Environment-specific settings are maintained under
environments/, ensuring that the desired state for each environment is version-controlled.
- A scheduled CI/CD pipeline runs periodically to check for configuration drift.
- The pipeline executes:
to compare the desired state in Git with the actual cluster state.
helmfile -e <environment> diff
- If a drift is detected, the pipeline can either:
- Automatically reconcile the state by running
helmfile apply. - Notify the DevOps team for manual intervention.
- Automatically reconcile the state by running
- A more efficient approach involves using [Kubernetes Event Exporter](https://github.com/resmoio/kubernetes-event-exporter) to listen for changes in resources annotated with
app.kubernetes.io/managed-by. - When a relevant resource is modified, an event is sent to a webhook that triggers the CD pipeline for reconciliation.
- There will be an unnecessary trigger for the CD pipeline as the reconciliation will also result in an update event firing, but since the resources are reconciled no further update events will be fired.
This GitOps implementation ensures that cluster configurations are always in sync with the desired state defined in Git. It enables both scheduled drift detection and event-driven reconciliation, providing an automated and efficient way to manage Kubernetes deployments.