{"id":13547849,"url":"https://github.com/stefanprodan/openfaas-flux","last_synced_at":"2025-04-02T20:31:01.386Z","repository":{"id":55013080,"uuid":"133570119","full_name":"stefanprodan/openfaas-flux","owner":"stefanprodan","description":"OpenFaaS Kubernetes cluster state management with FluxCD","archived":true,"fork":false,"pushed_at":"2021-01-15T09:27:56.000Z","size":3938,"stargazers_count":79,"open_issues_count":0,"forks_count":41,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-11-03T16:37:55.656Z","etag":null,"topics":["ci-cd","fluxcd","gitops","helm","kubernetes","openfaas","secrets-management"],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stefanprodan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-05-15T20:32:49.000Z","updated_at":"2023-11-01T10:12:25.000Z","dependencies_parsed_at":"2022-08-14T09:01:08.148Z","dependency_job_id":null,"html_url":"https://github.com/stefanprodan/openfaas-flux","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefanprodan%2Fopenfaas-flux","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefanprodan%2Fopenfaas-flux/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefanprodan%2Fopenfaas-flux/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stefanprodan%2Fopenfaas-flux/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stefanprodan","download_url":"https://codeload.github.com/stefanprodan/openfaas-flux/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246887880,"owners_count":20850157,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ci-cd","fluxcd","gitops","helm","kubernetes","openfaas","secrets-management"],"created_at":"2024-08-01T12:01:01.899Z","updated_at":"2025-04-02T20:30:56.367Z","avatar_url":"https://github.com/stefanprodan.png","language":"HTML","funding_links":[],"categories":["HTML"],"sub_categories":[],"readme":"# OpenFaaS GitOps workflow with Flux and Helm v3\n\nThis is a step-by-step guide on how to set up a [GitOps](https://www.weave.works/blog/kubernetes-anti-patterns-let-s-do-gitops-not-ciops)\nworkflow for OpenFaaS with Flux CD and its Helm Operator.\nGitOps is a way to do Continuous Delivery, it works by using Git as a source of truth for \ndeclarative infrastructure and workloads. In practice this means using `git push`\ninstead of `kubectl apply/delete` or `helm install/upgrade`. \n\n[OpenFaaS](https://www.openfaas.com/) is an open source function-as-a-service platform for Kubernetes.\nWith OpenFaaS you can package your code or an existing binary in a Docker image to get a highly scalable endpoint with auto-scaling and metrics. \n\n[Flux](https://fluxcd.io) is a GitOps operator for Kubernetes that keeps your cluster state is sync with a Git repository.\nBecause Flux is pull based and also runs inside Kubernetes, you don't have to expose the cluster\ncredentials outside your production environment.\nOnce you enable Flux on your cluster any changes in your production environment are done via\npull request with rollback and audit logs provided by Git. \n\nYou can define the desired state of your cluster with Helm charts, Kubernetes deployments, network policies and \neven custom resources like OpenFaaS functions or sealed secrets. Flux implements a control loop that continuously \napplies the desired state to your cluster, offering protection against harmful actions like deployments deletion or \npolicies altering.\n\n### Prerequisites\n\nYou'll need a Kubernetes cluster v1.11 or newer with load balancer support, a GitHub account, git and kubectl installed locally.\n\nOn GitHub, fork the [openfaas-flux](https://github.com/stefanprodan/openfaas-flux) repository and clone it locally\n(replace `stefanprodan` with your GitHub username): \n\n```sh\ngit clone https://github.com/stefanprodan/openfaas-flux\ncd openfaas-flux\n```\n\nInstall Helm v3 and fluxctl for macOS with Homebrew:\n\n```sh\nbrew install helm fluxctl\n```\n\nOn Windows you can use Chocolatey:\n\n```sh\nchoco install kubernetes-helm fluxctl\n```\n\n### Install Flux and Helm Operator\n\nAdd FluxCD repository to Helm repos:\n\n```bash\nhelm repo add fluxcd https://charts.fluxcd.io\n```\n\nCreate the `fluxcd` namespace:\n\n```sh\nkubectl create ns fluxcd\n```\n\nInstall Flux by specifying your fork URL (replace `stefanprodan` with your GitHub username): \n\n```bash\nhelm upgrade -i flux fluxcd/flux --wait \\\n--namespace fluxcd \\\n--set git.url=git@github.com:stefanprodan/openfaas-flux \n```\n\nInstall the `HelmRelease` Kubernetes custom resource definition:\n\n```sh\nkubectl apply -f https://raw.githubusercontent.com/fluxcd/helm-operator/master/deploy/flux-helm-release-crd.yaml\n```\n\nInstall Flux Helm Operator with ***Helm v3*** support:\n\n```bash\nhelm upgrade -i helm-operator fluxcd/helm-operator --wait \\\n--namespace fluxcd \\\n--set git.ssh.secretName=flux-git-deploy \\\n--set helm.versions=v3\n```\n\n### Setup Git sync\n\nAt startup, Flux generates a SSH key and logs the public key. Find the public key with:\n\n```bash\nfluxctl identity --k8s-fwd-ns fluxcd\n```\n\nIn order to sync your cluster state with git you need to copy the public key and \ncreate a **deploy key** with **write access** on your GitHub repository.\n\nOpen GitHub, navigate to your repository, go to _Settings \u003e Deploy keys_ click on _Add deploy key_, check \n_Allow write access_, paste the Flux public key and click _Add key_.\n\nAfter a couple of seconds Flux will create the `openfaas` and `openfaas-fn` namespaces and will install the OpenFaaS Helm release.\n\nCheck the OpenFaaS deployment status:\n\n```\nwatch kubectl -n openfaas get helmrelease openfaas\n```\n\n### Manage Helm releases with Flux\n\nThe Helm operator provides an extension to Flux that automates Helm chart releases.\nA chart release is described through a Kubernetes custom resource named `HelmRelease`.\nThe Flux daemon synchronizes these resources from git to the cluster,\nand the Helm operator makes sure Helm charts are released as specified in the resources.\n\n![flux helm v3](docs/screens/flux-helm-v3.png)\n\nLet's take a look at the OpenFaaS definition by running `cat ./releases/openfaas.yaml` inside the git repo:\n\n```yaml\napiVersion: helm.fluxcd.io/v1\nkind: HelmRelease\nmetadata:\n  name: openfaas\n  namespace: openfaas\nspec:\n  releaseName: openfaas\n  chart:\n    repository: https://openfaas.github.io/faas-netes/\n    name: openfaas\n    version: 5.4.0\n  values:\n    generateBasicAuth: true\n    exposeServices: false\n    serviceType: LoadBalancer\n    operator:\n      create: true\n```\n\nThe `spec.chart` section tells Flux Helm Operator where is the chart repository and what version to install.\nThe `spec.values` are user customizations of default parameter values from the chart itself.\nChanging the version or a value in git, will make the Helm Operator upgrade the release.\n\nEdit the release and set two replicas for the queue worker with:\n\n```sh\ncat \u003c\u003c EOF | tee releases/openfaas.yaml\napiVersion: helm.fluxcd.io/v1\nkind: HelmRelease\nmetadata:\n  name: openfaas\n  namespace: openfaas\nspec:\n  releaseName: openfaas\n  chart:\n    repository: https://openfaas.github.io/faas-netes/\n    name: openfaas\n    version: 5.4.0\n  values:\n    generateBasicAuth: true\n    serviceType: LoadBalancer\n    operator:\n      create: true\n    queueWorker:\n      replicas: 2\nEOF\n```\n\nA list of all supported chart values can be found in the\n[faas-netes](https://github.com/openfaas/faas-netes/tree/master/chart/openfaas) repo.\n\nApply changes via git:\n\n```sh\ngit add -A \u0026\u0026 \\\ngit commit -m \"scale up queue worker\" \u0026\u0026 \\\ngit push origin master \u0026\u0026 \\\nfluxctl sync --k8s-fwd-ns fluxcd\n```\n\nNote that Flux does a git-cluster reconciliation every five minutes,\nthe `fluxctl sync` command can be used to speed up the synchronization.\n\nCheck that Helm Operator has upgraded the release and that the queue worker was scaled up:\n\n```sh\nwatch kubectl -n openfaas get pods\n```\n\nRetrieve the OpenFaaS credentials with:\n\n```sh\nPASSWORD=$(kubectl -n openfaas get secret basic-auth -o jsonpath=\"{.data.basic-auth-password}\" | base64 --decode) \u0026\u0026 \\\necho \"OpenFaaS admin password: $PASSWORD\"\n```\n\nFind the OpenFaaS gateway load balancer address with:\n\n```sh\nkubectl -n openfaas get svc gateway-external -o wide\n```\n\nNavigate to the gateway address on port `8080` in your browser and login with the `admin` user and the password retrieved earlier.\n\n### Manage OpenFaaS functions with Flux\n\nAn OpenFaaS function is described through a Kubernetes custom resource named `function`.\nThe Flux daemon synchronizes these resources from git to the cluster,\nand the OpenFaaS Operator creates for each function a Kubernetes deployment and a ClusterIP service as \nspecified in the resources.\n\n![functions](docs/screens/flux-openfaas-operator.png)\n\nYou'll use a Helm chart stored in git to bundle multiple functions and manage the install and upgrade process.\n\nThe functions chart contains two function manifests, certinfo and podinfo:\n\n```\n./functions/\n├── Chart.yaml\n├── templates\n│   ├── certinfo.yaml\n│   └── podinfo.yaml\n└── values.yaml\n```\n\nYou can add. modify or remove functions in the `functions/templates` dir and Flux Helm Operator will create, update or \ndelete functions in your cluster according to the changes pushed to the master branch.\n\nInstall the chart by setting `fluxcd.io/ignore: \"false\"` (replace `stefanprodan` with your GitHub username): \n\n```sh\ncat \u003c\u003c EOF | tee releases/functions.yaml\napiVersion: helm.fluxcd.io/v1\nkind: HelmRelease\nmetadata:\n  name: functions\n  namespace: openfaas-fn\n  annotations:\n    fluxcd.io/ignore: \"false\"\nspec:\n  releaseName: functions\n  chart:\n    git: git@github.com:stefanprodan/openfaas-flux\n    ref: master\n    path: functions\nEOF\n```\n\nThe above manifest instructs Helm Operator to clone the git repository using Flux SSH key\nand install or upgrade the `functions` chart in the openfaas-fn namespace.\n\nApply changes via git:\n\n```sh\ngit add -A \u0026\u0026 \\\ngit commit -m \"install functions\" \u0026\u0026 \\\ngit push origin master \u0026\u0026 \\\nfluxctl sync --k8s-fwd-ns fluxcd\n```\n\nList the installed functions with:\n\n```sh\nkubectl -n openfaas-fn get functions\n```\n\nInvoke the certinfo function with:\n\n```sh\ncurl -d \"openfaas.com\" http://\u003cGATEWAY_ADDRESS\u003e:8080/function/certinfo\n```\n\n### Automate OpenFaaS functions updates\n\nFlux can be used to automate container image updates in your cluster.\nFlux periodically scans the pods running in your cluster and builds a list of all container images.\nUsing the image pull secrets, it connects to the container registries,\npulls the images metadata and stores the image tag list in memcached.\n\n![Flux automation](docs/screens/flux-image-updates.png)\n\nYou can enable the automate image tag updates by annotating your HelmReleases objects.\nYou can also control what tags should be considered for an update by using glob, regex or semantic version expressions.\n\nEdit the functions release and add container image update policies for the OpenFaaS functions\n(replace `stefanprodan` with your GitHub username): \n\n```sh\ncat \u003c\u003c EOF | tee releases/functions.yaml\napiVersion: helm.fluxcd.io/v1\nkind: HelmRelease\nmetadata:\n  name: functions\n  namespace: openfaas-fn\n  annotations:\n    fluxcd.io/automated: \"true\"\n    filter.fluxcd.io/certinfo: semver:~1.0\n    filter.fluxcd.io/podinfo: semver:~3.1\nspec:\n  releaseName: functions\n  chart:\n    git: git@github.com:stefanprodan/openfaas-flux\n    ref: master\n    path: functions\n  values:\n    certinfo:\n      image: stefanprodan/certinfo:1.0.0\n    podinfo:\n      image: stefanprodan/podinfo:3.1.0\nEOF\n```\n\nThe above annotations tell Flux to update the Helm release `values.\u003cfunction\u003e.image` \nevery time a new image is pushed to Docker Hub with a tag that matches the semver filter.\nNote that Flux only works with immutable image tags (`:latest` is not supported).\nEvery image tag must be unique, for this you can use the Git commit SHA or semver when tagging images.\n\nApply the update policies via git:\n\n```sh\ngit add -A \u0026\u0026 \\\ngit commit -m \"enable functions updates\" \u0026\u0026 \\\ngit push origin master \u0026\u0026 \\\nfluxctl sync --k8s-fwd-ns fluxcd\n```\n\nOnce the automation is enabled, Flux will apply the semver filter and update the functions images in git and in the cluster:\n\n![functions update](docs/screens/flux-image-update.png)\n\nVerify that podinfo version has been updated:\n\n```\n$ curl -s http://\u003cGATEWAY_ADDRESS\u003e:8080/function/podinfo/api/info | grep version\n\n\"version\": \"3.1.5\"\n```\n\n### Encrypt Kubernetes secrets in git\n\nIn order to store secrets safely in a public Git repo you can use the\n[Sealed Secrets controller](https://github.com/bitnami-labs/sealed-secrets)\nand encrypt your Kubernetes Secrets into SealedSecrets.\nThe SealedSecret can be decrypted only by the controller running in your cluster.\n\nThe Sealed Secrets controller has been installed by Flux in the `fluxcd` namespace,\nthe Helm release can be found in `releases/sealed-secrets.yaml`.\n\nInstall the kubeseal CLI:\n\n```sh\nbrew install kubeseal\n```\n\nAt startup, the sealed-secrets controller generates a RSA key and logs the public key.\nUsing kubeseal you can save your public key as `pub-cert.pem`,\nthe public key can be safely stored in Git, and can be used to encrypt secrets without direct access to the Kubernetes cluster:\n\n```sh\nkubeseal --fetch-cert \\\n--controller-namespace=adm \\\n--controller-name=sealed-secrets \\\n\u003e pub-cert.pem\n```\n\nGenerate a Kubernetes secret locally with kubectl:\n\n```bash\nkubectl create secret generic db-credentials \\\n--from-literal=user=my-db-user \\\n--from-literal=password=my-db-pass \\\n--dry-run \\\n-o json \u003e db-credentials.json\n```\n\nEncrypt the secret with kubeseal and add it to the functions chart:\n\n```sh\nkubeseal --format=yaml --cert=pub-cert.pem \\\n\u003c db-credentials.json \u003e functions/templates/db-credentials.yaml\n```\n\nEdit certinfo and add the secret to the function definition:\n\n```sh\ncat \u003c\u003c EOF | tee functions/templates/certinfo.yaml\napiVersion: openfaas.com/v1alpha2\nkind: Function\nmetadata:\n  name: certinfo\n  labels:\n{{ include \"functions.labels\" . | indent 4 }}\nspec:\n  name: certinfo\n  image: {{ .Values.certinfo.image }}\n  readOnlyRootFilesystem: true\n  secrets:\n    - db-credentials\nEOF\n```\n\nThe above configuration instructs the OpenFaaS operator to mount the db-credentials secret as a file inside the function\ncontainer at `/var/openfaas/secrets/`.\n\nDelete the plain text secret and apply changes via git:\n\n```sh\nrm db-credentials.json \u0026\u0026 \\\ngit add -A \u0026\u0026 \\\ngit commit -m \"add db credentials\" \u0026\u0026 \\\ngit push origin master \u0026\u0026 \\\nfluxctl sync --k8s-fwd-ns fluxcd\n```\n\nFlux will apply the sealed secret on your cluster and sealed-secrets controller will then decrypt it into a\nKubernetes secret.\n\n![SealedSecrets](https://github.com/fluxcd/helm-operator-get-started/blob/master/diagrams/flux-helm-operator-sealed-secrets.png)\n\nYou can read more about secrets management on the OpenFaaS docs [website](https://docs.openfaas.com/reference/secrets/).\n\n### Developer workflow\n\nYou'll be using the OpenFaaS CLI to create functions, build and push them to a container registry.\n\nInstall faas-cli and login to your instance:\n\n```sh\ncurl -sL https://cli.openfaas.com | sudo sh\n\necho $PASSWORD | faas-cli login -u admin --password-stdin \\\n--gateway http://\u003cGATEWAY_ADDRESS\u003e:8080\n```\n\nCreate a function using the Go template (replace `stefanprodan` with your Docker Hub username):\n\n```sh\nfaas-cli new myfn --lang go --prefix stefanprodan\n```\n\nImplement your function logic by editing the `myfn/handler.go` file.\n\nInitialize a Git repository for your function and commit your changes:\n\n```sh\ngit init\ngit add . \u0026\u0026 git commit -s -m \"Init function\"\n```\n\nBuild the container image by tagging it with the Git branch and commit short SHA:\n\n```sh\n$ faas-cli build --tag branch -f myfn.yml\n\nImage: stefanprodan/myfn:latest-master-eb656a6 built.\n```\n\nPush the image to Docker Hub with:\n\n```sh\n$ faas-cli push --tag branch -f myfn.yml\n\nPushing myfn [stefanprodan/myfn:latest-master-eb656a6] done.\n```\n\nGenerate the function Kubernetes custom resource with:\n\n```sh\nfaas-cli generate -n \"\" --tag branch --yaml myfn.yml \u003e myfn-k8s.yaml\n```\n\nEdit the generated YAML so that Flux can use Helm to control the version and labels:\n\n```sh\ncat \u003c\u003c EOF | tee functions/templates/myfn.yaml\napiVersion: openfaas.com/v1alpha2\nkind: Function\nmetadata:\n  name: myfn\n  labels:\n{{ include \"functions.labels\" . | indent 4 }}\nspec:\n  name: myfn\n  image: {{ .Values.myfn.image }}\nEOF\n```\n\nAdd your function container image to the chart values.yaml:\n\n```sh\ncat \u003c\u003c EOF | tee functions/values.yaml\ncertinfo:\n  image: stefanprodan/certinfo:1.0.0\npodinfo:\n  image: stefanprodan/podinfo:3.1.0\nmyfn:\n  image: stefanprodan/myfn:latest-master-eb656a6\nEOF\n```\n\nAdd your function to the Helm release and set a Flux filter using a glob expression:\n\n```sh\ncat \u003c\u003c EOF | tee releases/functions.yaml\napiVersion: helm.fluxcd.io/v1\nkind: HelmRelease\nmetadata:\n  name: functions\n  namespace: openfaas-fn\n  annotations:\n    fluxcd.io/automated: \"true\"\n    filter.fluxcd.io/certinfo: semver:~1.0\n    filter.fluxcd.io/podinfo: semver:~3.1\n    filter.fluxcd.io/myfn: glob:latest-master-*\nspec:\n  releaseName: functions\n  chart:\n    git: git@github.com:stefanprodan/openfaas-flux\n    ref: master\n    path: functions\n  values:\n    certinfo:\n      image: stefanprodan/certinfo:1.0.0\n    podinfo:\n      image: stefanprodan/podinfo:3.1.0\n    myfn:\n      image: stefanprodan/myfn:latest-master-eb656a6\nEOF\n```\n\nTo automate the whole process you can use the [OpenFaaS GitHub action](https://github.com/LucasRoesler/openfaas-action)\nto run faas-cli build and push on every commit to the master branch.\nFlux will detect master builds and will deploy the new images to your cluster.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstefanprodan%2Fopenfaas-flux","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstefanprodan%2Fopenfaas-flux","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstefanprodan%2Fopenfaas-flux/lists"}