Flux CD
Tags: gitops, flux, sre
Published: 2020-12-19 19:22:59

Originally published on [mccricardo.com](https://mccricardo.com/gitops-fluxcd/).

In it's website we can read that "Flux is a tool for keeping Kubernetes clusters in sync with sources of configuration (like Git repositories), and automating updates to configuration when there is new code to deploy." That is, obviously, powered by the GitOps toolkit have it not been developed (and open-sourced) by [Weaveworks](https://www.weave.works/).

Following the GitOps philosophy, Flux is/has:
  - **declarative** since it uses Git as its source of truth where the entire desired state is described;
  - **automated** because it can read state (described in YAML) and act upon it;
  - **auditable** due to Git history;
  - **designed for Kubernetes** from the ground up;
  - **out-of-the-box integrations** so that the wheel doesn't need to be reinvented;
  - **extensible** allowing for particular use cases to be added.

## Get the ball rolling

[Here](https://gitlab.com/mccricardo-blog-demos/gitops-flux-helm) you can find the demo we will be using in this tutorial to deploy [Prometheus](https://prometheus.io/) using it's official [Helm](https://helm.sh/) [chart](https://github.com/prometheus-community/helm-charts). We will be spinning a local Kubernetes cluster with [k3d](https://k3d.io/) and using Flux's [Helm Controller](https://toolkit.fluxcd.io/guides/helmreleases/) to handle the deploy. We need the following tools to make this happen:
  - [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/)
  - [k3d](https://k3d.io/)
  - [flux](https://github.com/fluxcd/flux2#flux-installation)
  - [Gitlab account](https://gitlab.com/)

We start by creating a local Kubernetes cluster with [k3d](https://k3d.io/):

```sh
k3d cluster create -a 2 gitops
k3d kubeconfig merge gitops --switch-context
```

To make our lives easier, we'll export a few environment variables to handle the authentication with [Gitlab](https://gitlab.com/):

```sh
export GITLAB_GROUP=<your-group>
export GITLAB_REPOSITORY=<your-repository>
export GITLAB_TOKEN=<your-token>
export GITLAB_USER=<your-user>
```

We bootstrap [Flux](https://fluxcd.io/), pointing it to our Gitlab repository where the configuration lives:
```sh
# Run the bootstrap command:
flux bootstrap gitlab \
  --owner=$GITLAB_USER \
  --repository=$GITLAB_REPOSITORY \
  --owner=$GITLAB_GROUP \
  --branch=master \
  --path=staging-cluster \
  --personal
```

We can check how the Prometheus deployment is going: 
```sh
# Check Flux progress
watch flux get helmreleases -n default

# Check Helm controler logs
kubectl -n flux-system logs -f deployment/helm-controller

# Check resource creation
watch kubectl get pods
```

At last we can view the fruits of our work be accessing Prometheus UI:
```sh
# Port-forward to access Prometheus
kubectl port-forward service/prometheus-server 8000:80

# Check webapp
http://localhost:8000/
```

You can clean up running:
```sh
k3d cluster delete gitops
```

## What did Flux do?

When we bootstrapped Flux, we pointed it at a repository and a specific folder ([staging-cluster](https://gitlab.com/mccricardo-blog-demos/gitops-flux-helm/-/tree/master/staging-cluster)) where the configuration resides. [prometheus-source.yaml](https://gitlab.com/mccricardo-blog-demos/gitops-flux-helm/-/blob/master/staging-cluster/prometheus-source.yaml) points to where the Helm chart lives enabling Flux to fetch it.
```yaml
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: HelmRepository
metadata:
  name: prometheus
  namespace: flux-system
spec:
  interval: 1m
  url: https://prometheus-community.github.io/helm-charts

```

Armed with the chart location, Flux can now look at [prometheus.yaml](https://gitlab.com/mccricardo-blog-demos/gitops-flux-helm/-/blob/master/staging-cluster/prometheus.yaml) and decide what to do with it.
```yaml
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
  name: prometheus
  namespace: default
spec:
  interval: 1m
  chart:
    spec:
      chart: prometheus
      version: '11.16.9'
      sourceRef:
        kind: HelmRepository
        name: prometheus
        namespace: flux-system
      interval: 1m
  values:
    pushgateway:
      enabled: false
```

In this example we're fetching version 11.16.9 of the chart, pointing at the HelmRepository defined in [prometheus-source.yaml](https://gitlab.com/mccricardo-blog-demos/gitops-flux-helm/-/blob/master/staging-cluster/prometheus-source.yaml) and passing a few values, which is the case of this example just disables Pushgateway.

We've just scratched the surface of what Flux can do but, with only a bit code we were able to deploy Prometheus effortlessly. Flux can do a lot more and, in case you're interested, take a look a the [documentation](https://toolkit.fluxcd.io/).