The flux-helmfile-controller is intended as an addon to FluxCD. Alongside the existing Kustomization
and HelmRelease
custom resources it introduces a new Helmfile
resource that allows doing deployments via helmfile. This introduces the powers of values templating and encryption to Flux Helm deployments.
This project is currently still in development and a work-in-progress. Use with caution.
Prerequisites:
- A kubernetes cluster with at least version 1.25.0 (for testing you can quickly set one up using
k3d cluster create
). kubectl
installed on your machine and its kubeconfig pointing to the cluster.helm
installed in your machine, to verify deployment.
To quickly install and test the controller, follow these steps:
-
Clone this repository:
git clone https://github.com/swoehrl-mw/flux-helmfile-controller.git && cd flux-helmfile-controller
. -
Install flux:
kubectl apply -f https://github.com/fluxcd/flux2/releases/latest/download/install.yaml
. -
Install the helmfile-controller:
kubectl apply -f https://github.com/swoehrl-mw/flux-helmfile-controller/releases/latest/download/manifests.yaml
. -
Deploy the example age key secret:
kubectl create secret generic sops-age-key --namespace=default --from-file=age.agekey=demo/age.agekey
. -
Deploy the example
GitRepository
andHelmfile
:kubectl apply -f demo/repo.yaml
. -
Wait a few seconds and then check the status of the helmfile deployment:
kubectl describe helmfile demo
. It should show the following:Status: Last Update: 2024-01-03T10:49:45Z Reason: <nil> Status: successful
-
Verify helmfile installed its chart:
helm status demo
:NAME: demo LAST DEPLOYED: Wed Jan 3 11:49:45 2024 NAMESPACE: default STATUS: deployed REVISION: 1 TEST SUITE: None
The helmfile-controller requires a running installation of FluxCD >= 2.0 (providing the GitRepository
custom resource). The controller should be installed into the same namespace as flux (by default flux-system
) as otherwise there might be communication problems with the flux-source-controller.
All needed manifests are in this repository in the manifests
folder and are using the flux-system
namespace. You can get the latest released version using https://github.com/swoehrl-mw/flux-helmfile-controller/releases/latest/download/manifests.yaml
.
To use the helmfile-controller you will need a git repository with a helmfile.yaml
. Create a Flux GitRepository
object pointing to that repo. Then create a Helmfile
object pointing to that repo object.
apiVersion: flux.maibornwolff.de/v1alpha1
kind: Helmfile
metadata:
name: my-helmfile
namespace: default # must be in the same namespace as the GitRepository
spec:
interval: 10m0s # Optional, How often should the controller run `helmfile apply` even if there are no changes
serviceAccountName: # Optional, name of a seviceaccount to impersonate for helmfile operations
sourceRef:
kind: GitRepository
name: mytest # Name of the GitRepository object, must be in same namespace as Helmfile object
path: my/path # Optional, path to the directory where helmfile.yaml is located, from repo root, can be skipped if helmfile.yaml is in root
environment: default # Optional, environment to use for `helmfile -e`
decryption: # Optional, only needed if the helmfile uses encrypted values/secrets
provider: sops-age # Provider to use for decryption, currently only sops-age is supported
secretRef:
name: sops-age-key # Name of a secret in the same namespace that has a key `age.agekey` with the private age key
options: # Optional, options related to helmfile execution
timeout: 10m # Optional, timeout after which apply/sync/destroy operations are aborted
retries: -1 # Optional, number of retries in case of helmfile failures, 0 means never, negative means retry forever, default is retry forever
prune: false # Optional, if set to true `helmfile destroy` will be run on deletion of object, otherwise the helm releases will be kept to avoid accidental deletion
To create the secret for decryption use the following command: kubectl create secret generic sops-age-key --namespace=default --from-file=age.agekey=age.agekey
.
After the object has been created, the controller will run helmfile sync
. And for each change to either the Helmfile
object or for any new revision of the git repo or after spec.interval
the controller will reconcile by running helmfile apply
.
If you want to force an immediate reconcile or want to run a sync
instead of apply
, add an action label to the object: kubectl label helmfile my-helmfile controller/action=sync
. The controller will then execute an immediate helmfile sync
and will delete the label afterwards.
To uninstall the releases, simply delete the Helmfile
object after having updated with options.prune: true
. The controller will then run helmfile destroy
. Note that the decryption secret and the GitRepository
must still exist for the controller to successfully run. If the secret is missing or the GitRepository object has been deleted as well the controller will silently end the reconcile instead of blocking. You must then delete the helm releases manually.
To develop and run the controller locally you need the following prerequisites:
- Rust and
cargo
installed (use the current stable version) - A local kubernetes cluster (e.g. using k3d:
k3d cluster create dev
) kubectl
,helm
andhelmfile
installed
To run the service locally follow these steps:
- Make sure your kubernetes cluster is stared and your kubeconfig points at it
- Install flux:
kubectl apply -f https://github.com/fluxcd/flux2/releases/latest/download/install.yaml
- Build the controller:
cargo build
- Generate the CRD yaml and apply it:
cargo run --bin devhelper && kubectl apply -f manifests/crd.yaml
- In a separate terminal start a port-forward for the flux source controller:
kubectl port-forward svc/source-controller -n flux-system 8080:80
- Start the controller:
SOURCE_CONTROLLER_HOST=localhost:8080 cargo run --bin controller
- From a separate terminal you can now apply
GitRepository
andHelmfile
manifests