Terraform helps you create and automate the running infrastructure, like your Kubernetes
cluster. Then, Flux CD helps you synchronize
the state
of your infrastructure using Git
as the source of truth, and follow GitOps
principles.
In this tutorial, you will learn to:
- Use
Terraform
modules, to automate all the steps required to provision your infrastructure. - Create
Flux CD
resources, to keep yourKubernetes
cluster applications state synchronized with aGit
repository (useGitOps
principles).
After finishing all the steps from this tutorial, you should have a fully functional DOKS
cluster with Flux CD
deployed, that will:
- Handle cluster reconciliation, via the Source Controller.
- Handle
Helm
releases, via the Helm Controller.
- Introduction
- Prerequisites
- Understanding Flux CD Concepts for Automated Helm Releases
- Step 1 - Initializing Terraform Backend
- Step 2 - Bootstrapping DOKS and Flux CD
- Step 3 - Inspecting DOKS Cluster and Flux CD State
- Step 4 - Cloning the Flux CD Git Repository and Preparing the Layout
- Step 5 - Creating the Sealed Secrets Helm Release
- Step 6 [OPTIONAL] - Creating the Cert-Manager Helm Release
- Step 7 - Creating the Ingress Controller Helm Release
- Step 8 - Creating the Prometheus Stack Helm Release
- Step 9 - Creating the Loki Stack Helm Release
- Step 10 - Creating the Velero Helm Release
- Conclusion
To complete this tutorial, you will need:
-
A GitHub repository and
branch
, forFlux CD
to store your cluster and sample applicationmanifests
.Important note:
The GitHub
repository
(andbranch
) must be created beforehand - the DigitalOcean Terraform module used in this tutorial doesn't provision one for you automatically. -
A GitHub personal access token that has the
repo
permissions set. TheTerraform
module used in this tutorial, needs it in order to create theSSH
deploy key, as well as to commit theFlux CD
manifests in yourGit
repository. -
A
DigitalOcean
access token, for creating/managing theDOKS
cluster. Please follow the officialDigitalOcean
tutorial on how to create a personal access token. Copy thetoken
value and save it somewhere safe. -
A dedicated
DO Spaces
bucket for the following:Terraform
state file (e.g.:terraform
).Loki
data storage (e.g.:loki-storage
).Velero
backups storage (e.g.:velero-backups-storage
).
Please follow the official
DigitalOcean
tutorial on how to create each. Make sure that it is set torestrict file listing
for security reasons. -
Access keys, for DigitalOcean Spaces (S3-compatible object storage). Please follow the official
DigitalOcean
tutorial on how to manage access keys. Copy thekey
andsecret
value, and save each in a localenvironment
variable for later use (make sure to replace the<>
placeholders accordingly):export DO_SPACES_ACCESS_KEY="<YOUR_DO_SPACES_ACCESS_KEY>" export DO_SPACES_SECRET_KEY="<YOUR_DO_SPACES_SECRET_KEY>"
-
A Git client, for cloning the
Starter Kit
repository. -
HashiCorp Terraform CLI, for provisioning the infrastructure.
-
Doctl CLI, for
DigitalOcean
API interaction. -
Kubectl CLI, for
Kubernetes
interaction. -
Flux CLI, for
Flux CD
interaction. -
Kubeseal, for encrypting secrets and
Sealed Secrets Controller
interaction.
The way Flux CD
knows how to handle Helm
releases is via a dedicated custom resource definition, the HelmRelease. Next, each HelmRelease
makes use of a HelmRepository CRD, to fetch the required chart to install.
You have some familiarity now with Helm
installations performed via the command line interface (each section of the Starter Kit
makes use of it). Flux CD
is achieving the same thing via the Helm Controller. You define manifests
that make use of specific CRDs (HelmRepository
, HelmRelease
), which in turn tell Flux CD
how to perform the same steps as you did when using the Helm CLI
.
The HelmRepository
CRD is used by Flux CD
to handle Helm repositories
, and to fetch
the available charts
(the CLI
equivalent of helm repo add <name> <url>
and helm repo update
).
Typical structure of a HelmRepository
manifest, looks like below:
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: HelmRepository
metadata:
name: ambassador
namespace: flux-system
spec:
interval: 10m0s
url: https://app.getambassador.io
Explanations for the above configuration:
<kind>
: Tells Flux CD what type ofCRD
the manifest is using (HelmRepository
, in this example).<metadata.name>
: Name of theHelmRepository
CRD (ambassador
, in this example).<metadata.namespace>
: Namespace to use for theHelmRepository
resource (flux-system
, in this example).<spec.interval>
: Time interval to use for synchronizing with the remote Helm repository (to fetch new chart releases metadata - CLI equivalent of:helm repo update
).<spec.url>
: Helm charts repository URL.
The HelmRelease
CRD is used by Flux CD
to handle Helm releases
in your DOKS
cluster (the CLI
equivalent of helm install <name> <chart> -f <values.yaml>
). It can also take care of upgrades
, as well as how to recover
in case of a failure, like: how many retries
to perform for a failed install
operation, rollbacks
, etc.
Each HelmRelease
makes use of a source
type, so that it knows where to pull the Helm
chart from:
- HelmRepository, for use with
Helm
chart repositories. - GitRepository, for use with
Git
repositories. - S3 Bucket, for use with
S3
compatible buckets.
Typical structure of a HelmRelease
manifest, looks like below:
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: ambassador-stack
namespace: flux-system
spec:
chart:
spec:
chart: edge-stack
sourceRef:
kind: HelmRepository
name: ambassador
version: 7.2.2
install:
createNamespace: true
interval: 1m0s
targetNamespace: ambassador
Explanations for the above configuration:
<kind>
: Tells Flux CD what type ofCRD
the manifest is using (HelmRelease
, in this example).<metadata.name>
: Name of theHelmRelease
CRD (ambassador-stack
, in this example).<metadata.namespace>
: Namespace to use for theHelmRelease
resource (flux-system
, in this example).<chart.spec.chart>
: Specifies thechart name
to fetch and install from theHelmRepository
(ambassador
, in this example).<chart.spec.sourceRef.kind>
: Tells Flux CD to use aHelmRepository
resource for fetching Helm charts (this is a good example that illustrates CRDs dependency).<chart.spec.sourceRef.name>
: HelmRepository CRD name to reference.<chart.spec.version>
: version of the Helm chart to install.<spec.install.createNamespace>
: Tells Flux CD if a namespace needs to be created before installing the chart (Helm CLI equivalent of:helm install --create-namespace
).<spec.interval>
: Time interval at which to reconcile the Helm release.<spec.targetNamespace>
: Namespace to place the Helm release (Helm CLI equivalent of:helm install --namespace <name>
).
Each Flux CD HelmRelease
can override values
via a values file - the equivalent of helm install <name> <chart> -f values.yaml
, or by setting each value individually - the equivalent of helm instal <name> <chart> --set <key> <value>
.
Flux CD
lets you override Helm
values via two spec types:
<spec.values>
: Allows you to override valuesinline
as seen in a standardvalues.yaml
file). This is the equivalent of:helm install -f <values_file>
.<spec.valuesFrom>
: Allows you to override valuesindividually
, by using each keyfully qualified path
from the values file (e.g.:aws.access_key_id
). This is the equivalent ofhelm install --set <key> <value>
.
Typical usage of spec.values
:
...
spec:
values:
loki:
enabled: true
config:
schema_config:
configs:
- from: "2020-10-24"
store: boltdb-shipper
object_store: aws
schema: v11
index:
prefix: index_
period: 24h
...
Explanations for the above configuration:
<spec.values>
: This key holds the original
Helm values
file content, just as when using the CLI
variant: helm install -f <values.yaml>
.
When using HelmReleases
, the <spec.values>
field copies
the values file content exactly
as seen in the YAML
file. It means that sensitive
data, like DO Spaces
credentials or DO API
token will be exposed, and that is not a good thing. What Flux CD
allows you to do in this case, is to override
values from Kubernetes Secrets
.
Typical usage of spec.valuesFrom
in combination with a Kubernetes Secret
(the below example expects that the do-credentials
Kubernetes secret to be created beforehand):
spec:
valuesFrom:
- kind: Secret
name: do-credentials
valuesKey: spaces_access_key
targetPath: aws.access_key_id
Explanations for the above configuration:
<spec.valuesFrom.kind>
: Kind of the values referent (KubernetesSecret
, in this example - can be aConfigMap
as well).<spec.valuesFrom.name>
: Name of the values referent (e.g. KubernetesSecret
), in thesame namespace
as theHelmRelease
.<spec.valuesFrom.valuesKey>
: The data key where a specific value can be found (defaults tovalues.yaml
when omitted).<spec.valuesFrom.targetPath>
: TheYAML
dot notationpath
at which the value should be merged. When set, thevaluesKey
is expected to be a single flat value (defaults toNone
when omitted, which results in thevalues
gettingmerged
at theroot
).
You can have a combination of spec.values
for storing non-sensitive data, and spec.valuesFrom
that reference Kubernetes secrets for sensitive data. In the end, each Flux CD HelmRelease
will merge
all the values together, so you can benefit from both worlds. In fact, this is how Helm
works, so the same principles apply.
In a GitOps
flow, Kubernetes Secrets
cannot be stored
directly using Git
, so you're going to use Sealed Secrets
to encrypt sensitive data.
Sealed Secrets
allows you to encrypt
generic Kubernetes
secrets and store
them safely
in Git
(even in public
repositories). Then, Flux CD
will create a corresponding Sealed Secret Object
in your cluster when syncing
the Git
repository. Sealed Secrets Controller
notices the sealed objects, and decrypts each to a classic Kubernetes secret. Applications can consume the secrets as usual.
Flux CD Sealed Secrets GitOps Flow:
For more details, please refer to Section 08 - Encrypt Kubernetes Secrets Using Sealed Secrets.
Next, you will learn how to provision the DOKS
cluster and Flux CD
, using Terraform
.
In this step, you're going to initialize the Terraform
backend. A DO Spaces
bucket for storing the Terraform
state file is highly recommended because you do not have to worry about exposing sensitive
data, as long as the space is private
of course. Another advantage is that the state
of your infrastructure
is backed up, so you can re-use it when the workspace
is lost. Having a shared
space for team members is desired as well, in order to perform collaborative
work via Terraform
.
First, clone the Starter Kit
Git repository on your local machine, and navigate to the terraform
directory:
git clone https://github.com/digitalocean/Kubernetes-Starter-Kit-Developers.git
cd Kubernetes-Starter-Kit-Developers/15-automate-with-terraform-flux/assets/terraform
Next, rename the backend.tf.sample
file provided by the Starter Kit
repository to backend.tf
:
cp backend.tf.sample backend.tf
Then, open backend.tf
using a text editor of your choice (preferably with Terraform
lint support), and replace the <>
placeholders accordingly (explanations for each can be found inside). For example, you can use VS Code:
code backend.tf
Finally, initialize the Terraform
backend. You're going to use the DO Spaces
access and secret key, created at Step 5.
from Prerequisites:
terraform init --backend-config="access_key=$DO_SPACES_ACCESS_KEY" --backend-config="secret_key=$DO_SPACES_SECRET_KEY"
The output looks similar to (check for the Successfully configured the backend "s3"!
message):
Initializing the backend...
Successfully configured the backend "s3"! Terraform will automatically
use this backend unless the backend configuration changes.
Initializing provider plugins...
- Finding hashicorp/kubernetes versions matching "2.3.2"...
- Finding gavinbunney/kubectl versions matching "1.11.2"...
...
In the next step, you will create the DOKS
cluster and provision Flux CD
, using Terraform
.
In this step, you're going to use a custom Terraform
module provided by DigitalOcean - DOKS-FluxCD, to provision your Kubernetes
cluster and deploy Flux CD
.
First, change directory to 15-automate-with-terraform-flux/assets/terraform
, from where you cloned the Starter Kit
Git repository:
cd Kubernetes-Starter-Kit-Developers/15-automate-with-terraform-flux/assets/terraform
Next, rename the main.tf.sample
file provided by the Starter Kit
repository to main.tf
:
cp main.tf.sample main.tf
Then, open main.tf
using an editor of your choice (preferably with Terraform
lint support), and replace the <>
placeholders accordingly (explanations for each can be found inside). For example, you can use VS Code:
code main.tf
Next, run Terraform
and inspect infrastructure changes:
terraform plan -out starter_kit_flux_cluster.out
Finally, if everything looks good, apply changes using Terraform
:
terraform apply "starter_kit_flux_cluster.out"
After running above steps, you should have a fully functional Kubernetes
cluster and Flux CD
deployed. In the next step, you're going to inspect the state of your DOKS
cluster, as well as Flux CD
.
First, please navigate to DOKS panel from your DigitalOcean
account, to visualize Kubernetes
cluster state:
Next, check that the Terraform
state file is saved in your DO Spaces bucket. Bucket listing looks similar to:
Finally, the Flux CD manifests
for your DOKS
cluster should be present in your Git
repository as well:
First, you have to set the kubectl
context to point to your DOKS
cluster. List the available Kubernetes
clusters first:
doctl k8s cluster list
Point kubectl
to your cluster (make sure to replace the <>
placeholders accordingly):
doctl k8s cluster kubeconfig save <your_doks_cluster_name>
Please check that the context was set, and that it's pointing to your Kubernetes
cluster:
kubectl config get-contexts
List cluster nodes, and make sure that they're in a healthy state (STATUS
column says Ready
):
kubectl get nodes
The output looks similar to:
NAME STATUS ROLES AGE VERSION
test-fluxcd-cluster-pool-8z9df Ready <none> 3d2h v1.21.3
test-fluxcd-cluster-pool-8z9dq Ready <none> 3d2h v1.21.3
test-fluxcd-cluster-pool-8z9dy Ready <none> 3d2h v1.21.3
Flux
provides a CLI
binary, which you can use for provisioning Flux CD
itself, as well as for main system interaction. You can also use it to export manifests
and create Flux CD resources
for your DOKS
cluster.
First, you can perform some sanity checks
via:
flux check
The output looks similar to the following:
► checking prerequisites
✔ kubectl 1.21.3 >=1.18.0-0
✔ Kubernetes 1.21.2 >=1.16.0-0
► checking controllers
✗ helm-controller: deployment ready
► ghcr.io/fluxcd/helm-controller:v0.11.1
✔ kustomize-controller: deployment ready
► ghcr.io/fluxcd/kustomize-controller:v0.13.1
✔ notification-controller: deployment ready
► ghcr.io/fluxcd/notification-controller:v0.15.0
✔ source-controller: deployment ready
► ghcr.io/fluxcd/source-controller:v0.15.3
✔ all checks passed
Then, inspect all Flux CD
resources via:
flux get all
The output looks similar to the following (long commit hashes were abbreviated in the output, for simplicity). Notice the gitrepository/flux-system
component fetching the latest revision from your main branch, as well as the kustomization/flux-system
component:
NAME READY MESSAGE REVISION SUSPENDED
gitrepository/flux-system True Fetched revision: main/1d69... main/1d69... False
NAME READY MESSAGE REVISION SUSPENDED
kustomization/flux-system True Applied revision: main/1d69... main/1d69c... False
In case you need to perform some troubleshooting, and see what Flux CD
is doing, you can access the logs via:
flux logs
The output looks similar to the following:
...
2021-07-20T12:31:36.696Z info GitRepository/flux-system.flux-system - Reconciliation finished in 1.193290329s, next run in 1m0s
2021-07-20T12:32:37.873Z info GitRepository/flux-system.flux-system - Reconciliation finished in 1.176637507s, next run in 1m0s
...
Finally, check that Flux CD
points to your Git
repository:
kubectl get gitrepositories.source.toolkit.fluxcd.io -n flux-system
The output looks similar to (notice the URL
column value - should point to your Git
repository, and the READY
state set to True
):
NAME URL READY STATUS AGE
flux-system ssh://[email protected]/test-starterkit/starterkit_fra1.git True Fetched revision: main/1d69... 21h
In the next step, you will prepare the Git
repository layout for use in this tutorial. Although Flux CD
doesn't care about the directory structure of your Git
repository (it performs a recursive search for manifests), it's best practice to keep things organized, and follow naming conventions as much as possible, to avoid frustration in the future.
In this step, you will learn how to organize
your Git
repository used by Flux CD
to sync your DOKS
cluster state
. For simplicity, this tutorial is based on a monorepo
structure, and is using a single environment
to hold all your manifests.
Please make sure that the following steps are performed in order, before anything else:
-
First, clone your Flux CD
Git
repository. This is the main repository used for yourDOKS
cluster reconciliation (please replace the<>
placeholders accordingly):git clone https://github.com/<YOUR_GITHUB_USER>/<YOUR_GITHUB_REPOSITORY_NAME>.git
Explanations for the above command:
<YOUR_GITHUB_USER>
- your GitHubusername
as defined inmain.tf
file (<github_user>
variable).<YOUR_GITHUB_REPOSITORY_NAME>
- your Flux CDGitHub repository
used for yourDOKS
clusterreconciliation
as defined inmain.tf
file (<git_repository_name>
variable).
-
Next, change directory where your Flux CD
Git
repository was cloned. -
Then, checkout the correct branch as defined in
main.tf
file forFlux CD
to use (<git_repository_branch>
variable). -
Now, create the
directory structure
to store Flux CDHelmRepository
,HelmRelease
andSealedSecret
manifests for each component of theStarter Kit
. Please replace<YOUR_GIT_REPOSITORY_SYNC_PATH>
with yourFlux CD
cluster sync directory path, as defined by the<git_repository_sync_path>
variable frommain.tf
file:FLUXCD_HELM_MANIFESTS_PATH="<YOUR_GIT_REPOSITORY_SYNC_PATH>/helm" mkdir -p "${FLUXCD_HELM_MANIFESTS_PATH}/repositories" mkdir -p "${FLUXCD_HELM_MANIFESTS_PATH}/releases" mkdir -p "${FLUXCD_HELM_MANIFESTS_PATH}/secrets"
-
Finally, add the
.gitignore
file toavoid
committingunencrypted
Helm value files in your repository, that may contain sensitive data. Using your favoritetext editor
, paste the following (below example is using theStarter Kit
naming convention):# Ignore all YAML files containing the `-values-` string. *-values-*.yaml # Do not ignore sealed YAML files. !*-sealed.yaml
After finishing all the steps from this tutorial, you should have a Git
repository structure similar to:
├── README.md
├── clusters
│ └── dev
│ ├── flux-system
│ │ ├── gotk-components.yaml
│ │ ├── gotk-sync.yaml
│ │ └── kustomization.yaml
│ └── helm
│ ├── releases
│ │ ├── ambassador-stack-v7.2.2.yaml
│ │ ├── loki-stack-v2.5.1.yaml
│ │ ├── prometheus-stack-v30.0.1.yaml
│ │ ├── sealed-secrets-v2.0.2.yaml
│ │ └── velero-v2.27.3.yaml
│ ├── repositories
│ │ ├── ambassador.yaml
│ │ ├── grafana.yaml
│ │ ├── prometheus-community.yaml
│ │ ├── sealed-secrets.yaml
│ │ └── vmware-tanzu.yaml
│ └── secrets
│ ├── do-api-credentials-sealed.yaml
│ ├── do-spaces-credentials-sealed.yaml
│ └── prometheus-stack-credentials-sealed.yaml
└── pub-sealed-secrets-dev-cluster.pem
Next, you're going to provision the required Flux CD
manifests for each component of the Starter Kit
. Then, you will inspect and commit each manifest to your Git
repository used by Flux CD
to reconcile your DOKS
cluster. For sensitive data, a Kubernetes Secrets
will be created and encrypted
using Sealed Secrets
, and then stored in your Git
repository as well.
First example will make use of the Flux CLI
for you to accommodate and get familiarized with creating manifests via the CLI
. Then, you will use the already prepared manifests
provided by the Starter Kit
repository, to speed up the steps from this tutorial.
You're going to start with the Sealed Secrets
Helm release first, because it's a prerequisite for the rest of the Starter Kit
components.
In this step, you will learn how to create manifests using the Flux CLI
, to define the Sealed Secrets
Helm release. Then, Flux
will trigger the Sealed Secrets Controller
installation process for your DOKS
cluster.
Please use the following steps, to create required manifests for the Sealed Secrets
Helm release:
-
First, change directory where your
Flux CD
Git repository was cloned. Also, please check that the required directory structure for this tutorial is created, and that theFLUXCD_HELM_MANIFESTS_PATH
environment variable is set (please refer to Step 4 - Cloning the Flux CD Git Repository and Preparing the Layout, for details). -
Then, create the
Sealed Secrets
HelmRepository manifest forFlux
:flux create source helm sealed-secrets \ --url="https://bitnami-labs.github.io/sealed-secrets" \ --interval="10m" \ --export > "${FLUXCD_HELM_MANIFESTS_PATH}/repositories/sealed-secrets.yaml"
Explanations for the above command:
--url
: Helm repository address.--interval
: Source sync interval (default1m0s
).--export
: Export inYAML
format to stdout.
The output looks similar to (you can notice that it has a similar structure as explained in Using HelmRepository CRD to Define Helm Repositories):
--- apiVersion: source.toolkit.fluxcd.io/v1beta1 kind: HelmRepository metadata: name: sealed-secrets namespace: flux-system spec: interval: 10m0s url: https://bitnami-labs.github.io/sealed-secrets
-
Next, fetch the
Starter Kit
values file forSealed Secrets
. Please make sure to inspect the values file first, and replace the<>
placeholders where needed:SEALED_SECRETS_CHART_VERSION="2.0.2" curl "https://raw.githubusercontent.com/digitalocean/Kubernetes-Starter-Kit-Developers/main/08-kubernetes-sealed-secrets/assets/manifests/sealed-secrets-values-v${SEALED_SECRETS_CHART_VERSION}.yaml" > "sealed-secrets-values-v${SEALED_SECRETS_CHART_VERSION}.yaml"
-
Now, create the
Sealed Secrets
HelmRelease manifest forFlux CD
.Kubeseal
CLI expects by default to find the controller in thekube-system
namespace and to be namedsealed-secrets-controller
, hence we override the release name via the--release-name
and--target-namespace
flags. This is not mandatory, butkube-system
is usually accessible only to power users (administrators):SEALED_SECRETS_CHART_VERSION="2.0.2" flux create helmrelease "sealed-secrets-controller" \ --release-name="sealed-secrets-controller" \ --source="HelmRepository/sealed-secrets" \ --chart="sealed-secrets" \ --chart-version "$SEALED_SECRETS_CHART_VERSION" \ --values="sealed-secrets-values-v${SEALED_SECRETS_CHART_VERSION}.yaml" \ --target-namespace="flux-system" \ --crds=CreateReplace \ --export > "${FLUXCD_HELM_MANIFESTS_PATH}/releases/sealed-secrets-v${SEALED_SECRETS_CHART_VERSION}.yaml"
Explanations for the above command:
--release-name
: What name to use for the Helm release (defaults to<target-namespace>-<HelmRelease-name>
otherwise).--source
: Source that contains the chart in the format<kind>/<name>.<namespace>
, where kind must be one of: (HelmRepository
,GitRepository
,Bucket
).--chart
: Helm chart name.--chart-version
: Helm chart version.--values
: Local path to values file.--target-namespace
: Namespace to install this release.--crds
: Upgrade CRDs policy, available options are: (Skip
,Create
,CreateReplace
).--export
: Export inYAML
format to stdout.
The output looks similar to (you can observe that it has a similar structure as explained in Using HelmRelease CRD to Install Helm Charts):
--- apiVersion: helm.toolkit.fluxcd.io/v2beta1 kind: HelmRelease metadata: name: sealed-secrets-controller namespace: flux-system spec: chart: spec: chart: sealed-secrets sourceRef: kind: HelmRepository name: sealed-secrets version: 2.0.2 interval: 1m0s releaseName: sealed-secrets-controller targetNamespace: flux-system install: crds: Create upgrade: crds: CreateReplace values: ingress: enabled: false
-
Finally, commit
Git
changes toremote
branch:SEALED_SECRETS_CHART_VERSION="2.0.2" git add "${FLUXCD_HELM_MANIFESTS_PATH}/repositories/sealed-secrets.yaml" git add "${FLUXCD_HELM_MANIFESTS_PATH}/releases/sealed-secrets-v${SEALED_SECRETS_CHART_VERSION}.yaml" git commit -am "Adding Sealed Secrets manifests for Flux CD" git push origin
After completing the above steps, Flux CD
will start your DOKS
cluster reconciliation
(in about one minute
or so, if using the default
interval). If you don't want to wait, you can always force
reconciliation via:
flux reconcile source git flux-system
After a few moments, please inspect the Flux CD Sealed Secrets
Helm release:
flux get helmrelease sealed-secrets-controller
The output looks similar to:
NAME READY MESSAGE REVISION SUSPENDED
sealed-secrets-controller True Release reconciliation succeeded 2.0.2 False
Look for the READY
column value - it should say True
. Reconciliation status is displayed in the MESSAGE
column, along with the REVISION
number, which represents the Helm
chart version
. Please bear in mind that some releases take longer to complete (like Prometheus
stack, for example), so please be patient.
Hints:
-
The
MESSAGE
column will displayReconciliation in progress
, as long as theHelmController
is performing the installation for the specifiedHelm
chart. If something goes wrong, you'll get another message stating the reason, so please make sure to check Helm release state. -
You can use the
--watch
flag for example:flux get helmrelease <name> --wait
, to wait until the command finishes. Please bear in mind that in this mode,Flux
will block your terminal prompt until the default timeout of5 minutes
occurs (can be overridden via the--timeout
flag). -
In case something goes wrong, you can search the
Flux
logs, and filterHelmRelease
messages only:flux logs --kind=HelmRelease
To be able to encrypt
secrets, you need the public key
that was generated by the Sealed Secrets Controller
when it was deployed by Flux CD
in your DOKS
cluster.
First, change directory where you cloned your Flux CD
Git repository, and do the following (please replace the <>
placeholders accordingly):
kubeseal --controller-namespace=flux-system --fetch-cert > pub-sealed-secrets-<YOUR_DOKS_CLUSTER_NAME_HERE>.pem
Note:
If for some reason the kubeseal
certificate fetch command hangs, you can use the following steps to work around this issue:
-
First, open another terminal window, and
expose
theSealed Secrets Controller
service on yourlocalhost
(you can useCTRL - C
to terminate, after fetching the public key):kubectl port-forward service/sealed-secrets-controller 8080:8080 -n flux-system &
-
Then, you can go back to your working terminal and fetch the public key (please replace the
<>
placeholders accordingly):curl --retry 5 --retry-connrefused localhost:8080/v1/cert.pem > pub-sealed-secrets-<YOUR_DOKS_CLUSTER_NAME_HERE>.pem
Finally, commit
the public key file to remote Git
repository for later use (it's safe
to do this, because the public key
is useless without the private key
which is stored in your DOKS
cluster only). Please run bellow commands, and make sure to replace the <>
placeholders accordingly:
git add pub-sealed-secrets-<YOUR_DOKS_CLUSTER_NAME_HERE>.pem
git commit -m "Adding Sealed Secrets public key for cluster <YOUR_DOKS_CLUSTER_NAME_HERE>"
git push origin
Important note:
In this tutorial the flux-system
namespace is used to hold Kubernetes Secrets
, so please make sure that it is restricted
to regular users/ applications via RBAC
.
Next, you're going to perform similar steps to define Helm
releases for the remaining components of the Starter Kit
.
If you want to have wildcard certificates
support for your cluster, you need to provision Cert-Manager
as well. This step is also required if proper TLS
termination is needed for the Nginx Ingress Controller
.
Steps to follow:
-
First, change directory where your
Flux CD
Git repository was cloned. Also, please check that the required directory structure for this tutorial is created, and that theFLUXCD_HELM_MANIFESTS_PATH
environment variable is set (please refer to Step 4 - Cloning the Flux CD Git Repository and Preparing the Layout, for details). -
Then, fetch the Jetstack
HelmRepository
manifest file provided by theStarter Kit
Git repository:curl "https://raw.githubusercontent.com/digitalocean/Kubernetes-Starter-Kit-Developers/main/15-automate-with-terraform-flux/assets/manifests/fluxcd/helm/repositories/jetstack.yaml" > "${FLUXCD_HELM_MANIFESTS_PATH}/repositories/jetstack.yaml"
-
Now, fetch the Cert-Manager
HelmRelease
manifest file provided by theStarter Kit
Git repository:CERT_MANAGER_CHART_VERSION="1.6.1" curl "https://raw.githubusercontent.com/digitalocean/Kubernetes-Starter-Kit-Developers/main/15-automate-with-terraform-flux/assets/manifests/fluxcd/helm/releases/cert-manager-v${CERT_MANAGER_CHART_VERSION}.yaml" > "${FLUXCD_HELM_MANIFESTS_PATH}/releases/cert-manager-v${CERT_MANAGER_CHART_VERSION}.yaml"
-
Next, inspect the downloaded
HelmRelease
manifest file using an editor of your choice (preferably withYAML
lint support), and adjust to your needs. For example, you can use VS Code (make sure to replace the<>
placeholders accordingly, if present):CERT_MANAGER_CHART_VERSION="1.6.1" code "${FLUXCD_HELM_MANIFESTS_PATH}/releases/cert-manager-v${CERT_MANAGER_CHART_VERSION}.yaml"
-
Finally, commit
Git
changes toremote
branch:CERT_MANAGER_CHART_VERSION="1.6.1" git add "${FLUXCD_HELM_MANIFESTS_PATH}/repositories/jetstack.yaml" git add "${FLUXCD_HELM_MANIFESTS_PATH}/releases/cert-manager-v${CERT_MANAGER_CHART_VERSION}.yaml" git commit -am "Adding Cert-Manager manifests for Flux CD" git push origin
After completing the above steps, Flux CD
will start your DOKS
cluster reconciliation
(in about one minute
or so, if using the default
interval). If you don't want to wait, you can always force
reconciliation via:
flux reconcile source git flux-system
After a few moments, please inspect the HelmRelease
status:
flux get helmrelease cert-manager
The output looks similar to:
NAME READY MESSAGE REVISION SUSPENDED
cert-manager True Release reconciliation succeeded v1.6.1 False
Look for the READY
column value - it should say True
. Reconciliation status is displayed in the MESSAGE
column, along with the REVISION
number, which represents the Helm
chart version
. Please bear in mind that some releases take longer to complete (like Prometheus
stack, for example), so please be patient.
Hints:
-
The
MESSAGE
column will displayReconciliation in progress
, as long as theHelmController
is performing the installation for the specifiedHelm
chart. If something goes wrong, you'll get another message stating the reason, so please make sure to check Helm release state. -
You can use the
--watch
flag for example:flux get helmrelease <name> --wait
, to wait until the command finishes. Please bear in mind that in this mode,Flux
will block your terminal prompt until the default timeout of5 minutes
occurs (can be overridden via the--timeout
flag). -
In case something goes wrong, you can search the
Flux
logs, and filterHelmRelease
messages only:flux logs --kind=HelmRelease
Next, you're going to create Flux CD
manifests for the Ambassador
(or Nginx
) ingress.
In this step, you will use pre-made manifests to create your preferred Ingress Controller
Helm release for Flux CD
. Then, Flux
will trigger the Ingress Controller
installation process for your DOKS
cluster.
There are two options available, depending on what Ingress Controller
you feel most comfortable:
Ambassador
Ingress Helm Release.Nginx
Ingress Helm Release.
Steps to follow:
-
First, change directory where your
Flux CD
Git repository was cloned. Also, please check that the required directory structure for this tutorial is created, and that theFLUXCD_HELM_MANIFESTS_PATH
environment variable is set (please refer to Step 4 - Cloning the Flux CD Git Repository and Preparing the Layout, for details). -
Then, fetch the
HelmRepository
manifest file provided by theStarter Kit
Git repository (please pick only one option, depending on whatIngress Controller
you want to install and configure):Ambassador
Ingress:curl "https://raw.githubusercontent.com/digitalocean/Kubernetes-Starter-Kit-Developers/main/15-automate-with-terraform-flux/assets/manifests/fluxcd/helm/repositories/ambassador.yaml" > "${FLUXCD_HELM_MANIFESTS_PATH}/repositories/ambassador.yaml"
Nginx
Ingress:curl "https://raw.githubusercontent.com/digitalocean/Kubernetes-Starter-Kit-Developers/main/15-automate-with-terraform-flux/assets/manifests/fluxcd/helm/repositories/kubernetes-community-nginx.yaml" > "${FLUXCD_HELM_MANIFESTS_PATH}/repositories/kubernetes-community-nginx.yaml"
-
Now, fetch the
HelmRelease
manifest file provided by theStarter Kit
Git repository (please pick only one option, depending on whatIngress Controller
you want to install and configure):Ambassador
Ingress:AMBASSADOR_CHART_VERSION="7.2.2" curl "https://raw.githubusercontent.com/digitalocean/Kubernetes-Starter-Kit-Developers/main/15-automate-with-terraform-flux/assets/manifests/fluxcd/helm/releases/ambassador-stack-v${AMBASSADOR_CHART_VERSION}.yaml" > "${FLUXCD_HELM_MANIFESTS_PATH}/releases/ambassador-stack-v${AMBASSADOR_CHART_VERSION}.yaml"
Nginx
Ingress:NGINX_CHART_VERSION="4.0.13" curl "https://raw.githubusercontent.com/digitalocean/Kubernetes-Starter-Kit-Developers/main/15-automate-with-terraform-flux/assets/manifests/fluxcd/helm/releases/nginx-v${NGINX_CHART_VERSION}.yaml" > "${FLUXCD_HELM_MANIFESTS_PATH}/releases/nginx-v${NGINX_CHART_VERSION}.yaml"
-
Next, inspect the downloaded
HelmRelease
manifest file using an editor of your choice (preferably withYAML
lint support), and adjust to your needs. For example, you can use VS Code. Make sure to replace the<>
placeholders accordingly, if present ((please pick only one option, depending on whatIngress Controller
you want to install and configure):Ambassador
Ingress:AMBASSADOR_CHART_VERSION="7.2.2" code "${FLUXCD_HELM_MANIFESTS_PATH}/releases/ambassador-stack-v${AMBASSADOR_CHART_VERSION}.yaml"
Nginx
Ingress:NGINX_CHART_VERSION="4.0.13" code "${FLUXCD_HELM_MANIFESTS_PATH}/releases/nginx-v${NGINX_CHART_VERSION}.yaml"
Hint:
Notice how the
HelmRelease
manifest configures remediation actions (you can visit Configuring Failure Remediation, for more details aboutHelm
install/upgrade failure remediation options available inFlux CD
):... install: createNamespace: true remediation: retries: 3 upgrade: remediation: retries: 3 ...
-
Finally, commit
Git
changes toremote
branch (please pick only one option, depending on whatIngress Controller
you want to install and configure):Ambassador
Ingress:AMBASSADOR_CHART_VERSION="7.2.2" git add "${FLUXCD_HELM_MANIFESTS_PATH}/repositories/ambassador.yaml" git add "${FLUXCD_HELM_MANIFESTS_PATH}/releases/ambassador-stack-v${AMBASSADOR_CHART_VERSION}.yaml" git commit -am "Adding Ambassador manifests for Flux CD" git push origin
Nginx
Ingress:NGINX_CHART_VERSION="4.0.13" git add "${FLUXCD_HELM_MANIFESTS_PATH}/repositories/kubernetes-community-nginx.yaml" git add "${FLUXCD_HELM_MANIFESTS_PATH}/releases/nginx-v${NGINX_CHART_VERSION}.yaml" git commit -am "Adding Nginx manifests for Flux CD" git push origin
After completing the above steps, Flux CD
will start your DOKS
cluster reconciliation
(in about one minute
or so, if using the default
interval). If you don't want to wait, you can always force
reconciliation via:
flux reconcile source git flux-system
After a few moments, please inspect the HelmRelease
status (please pick only one option, depending on the installed Ingress Controller
):
Ambassador
Ingress:
flux get helmrelease ambassador-stack
The output looks similar to:
NAME READY MESSAGE REVISION SUSPENDED
ambassador-stack True Release reconciliation succeeded 7.2.2 False
Nginx
Ingress:
flux get helmrelease ingress-nginx
The output looks similar to:
NAME READY MESSAGE REVISION SUSPENDED
ingress-nginx True Release reconciliation succeeded 4.0.13 False
Look for the READY
column value - it should say True
. Reconciliation status is displayed in the MESSAGE
column, along with the REVISION
number, which represents the Helm
chart version
. Please bear in mind that some releases take longer to complete (like Prometheus
stack, for example), so please be patient.
Hints:
-
The
MESSAGE
column will displayReconciliation in progress
, as long as theHelmController
is performing the installation for the specifiedHelm
chart. If something goes wrong, you'll get another message stating the reason, so please make sure to check Helm release state. -
You can use the
--watch
flag for example:flux get helmrelease <name> --wait
, to wait until the command finishes. Please bear in mind that in this mode,Flux
will block your terminal prompt until the default timeout of5 minutes
occurs (can be overridden via the--timeout
flag). -
In case something goes wrong, you can search the
Flux
logs, and filterHelmRelease
messages only:flux logs --kind=HelmRelease
Please refer to the Ambassador Ingress or Nginx Ingress tutorial, for more details about checking Ingress Controller
deployment status and functionality.
Next, you're going to create Flux CD
manifests for the Prometheus
stack.
In this step, you will use pre-made manifests to create the Prometheus
Helm release for Flux CD
. Then, Flux
will trigger the Prometheus
installation process for your DOKS
cluster. The Prometheus
stack deploys Grafana
as well, so you need to set the administrator
credentials for accessing the dashboards
. You will learn how to use kubeseal
CLI with Sealed Secrets Controller
to encrypt sensitive
data stored in Kubernetes Secrets
. Then, you will see how the Flux CD HelmRelease
manifest is used to reference
Grafana credentials
stored in the Kubernetes Secret
.
Steps to follow:
-
First, change directory where your
Flux CD
Git repository was cloned. Also, please check that the required directory structure for this tutorial is created, and that theFLUXCD_HELM_MANIFESTS_PATH
environment variable is set (please refer to Step 4 - Cloning the Flux CD Git Repository and Preparing the Layout, for details). -
Then, fetch the
Prometheus
HelmRepository manifest provided by theStarter Kit
Git repository:curl "https://raw.githubusercontent.com/digitalocean/Kubernetes-Starter-Kit-Developers/main/15-automate-with-terraform-flux/assets/manifests/fluxcd/helm/repositories/prometheus-community.yaml" > "${FLUXCD_HELM_MANIFESTS_PATH}/repositories/prometheus-community.yaml"
-
Next,
create
andencrypt
theKubernetes Secret
holding yourGrafana
dashboardadmin password
. Make sure that you have theSealed Secrets
public key exported as mentioned in Exporting the Sealed Secrets Controller Public Key (please replace the<>
placeholders accordingly):SEALED_SECRETS_PUB_KEY="<YOUR_SEALED_SECRETS_PUB_KEY_NAME_HERE>" GRAFANA_ADMIN_PASSWORD="<YOUR_GRAFANA_ADMIN_PASSWORD_HERE>" kubectl create secret generic "prometheus-stack-credentials" \ --namespace flux-system \ --from-literal=grafana_admin_password="${GRAFANA_ADMIN_PASSWORD}" \ --dry-run=client -o yaml | kubeseal --cert="${SEALED_SECRETS_PUB_KEY}" \ --format=yaml > "${FLUXCD_HELM_MANIFESTS_PATH}/secrets/prometheus-stack-credentials-sealed.yaml"
Explanations for the above command:
--namespace
: Namespace where the Kubernetes secret should be created.--from-literal
: Create a Kubernetes secret from a literal value containing thegrafana_admin_password
. Theprometheus-stack-credentials
secret andgrafana_admin_password
value is used by the prometheus-stack-v30.0.1.yaml manifest (spec.valuesFrom
key).--dry-run=client
: Exports the Kubernetes secret on your local machine using standard output (and afterwards, piped tokubeseal
to encrypt the final result).
-
Now, fetch the
Prometheus
HelmRelease manifest provided by theStarter Kit
Git repository:PROMETHEUS_CHART_VERSION="30.0.1" curl "https://raw.githubusercontent.com/digitalocean/Kubernetes-Starter-Kit-Developers/main/15-automate-with-terraform-flux/assets/manifests/fluxcd/helm/releases/prometheus-stack-v${PROMETHEUS_CHART_VERSION}.yaml" > "${FLUXCD_HELM_MANIFESTS_PATH}/releases/prometheus-stack-v${PROMETHEUS_CHART_VERSION}.yaml"
-
Then, inspect the downloaded Prometheus
HelmRelease
manifest using an editor of your choice (preferably withYAML
lint support), and adjust to your needs. For example, you can use VS Code (please make sure to replace the<>
placeholders accordingly, if present):PROMETHEUS_CHART_VERSION="30.0.1" code "${FLUXCD_HELM_MANIFESTS_PATH}/releases/prometheus-stack-v${PROMETHEUS_CHART_VERSION}.yaml"
Note: You can see how the
prometheus-stack-credentials
secret is referenced inside the PrometheusHelmRelease
manifest, by looking at below snippet:valuesFrom: - kind: Secret name: prometheus-stack-credentials # Kubernetes secret holding Prometheus stack credentials valuesKey: grafana_admin_password # Key from the `prometheus-stack-credentials` secret, holding the Grafana admin password targetPath: grafana.adminPassword # Helm value to override optional: false # Helm release will fail if value is not found
-
Finally, commit
Git
changes toremote
branch:PROMETHEUS_CHART_VERSION="30.0.1" git add "${FLUXCD_HELM_MANIFESTS_PATH}/repositories/prometheus-community.yaml" git add "${FLUXCD_HELM_MANIFESTS_PATH}/releases/prometheus-stack-v${PROMETHEUS_CHART_VERSION}.yaml" git add "${FLUXCD_HELM_MANIFESTS_PATH}/secrets/prometheus-stack-credentials-sealed.yaml" git commit -am "Adding Prometheus manifests for Flux CD" git push origin
After a few moments, please inspect the Prometheus HelmRelease
:
flux get helmrelease kube-prometheus-stack
The output looks similar to:
NAME READY MESSAGE REVISION SUSPENDED
kube-prometheus-stack True Release reconciliation succeeded 30.0.1 False
Look for the READY
column value - it should say True
. Reconciliation status is displayed in the MESSAGE
column, along with the REVISION
number, which represents the Helm
chart version
. Please bear in mind that some releases take longer to complete (like Prometheus
stack, for example), so please be patient.
Hints:
-
The
MESSAGE
column will displayReconciliation in progress
, as long as theHelmController
is performing the installation for the specifiedHelm
chart. If something goes wrong, you'll get another message stating the reason, so please make sure to check Helm release state. -
You can use the
--watch
flag for example:flux get helmrelease <name> --wait
, to wait until the command finishes. Please bear in mind that in this mode,Flux
will block your terminal prompt until the default timeout of5 minutes
occurs (can be overridden via the--timeout
flag). -
In case something goes wrong, you can search the
Flux
logs, and filterHelmRelease
messages only:flux logs --kind=HelmRelease
Now, check if the prometheus-stack-credentials
Kubernetes secret was created as well (then, you can use kubectl get secret prometheus-stack-credentials -n flux-system -o yaml
for secret contents inspection):
kubectl get secret prometheus-stack-credentials -n flux-system
Finally, perform a quick check of Prometheus
stack main services
, and PVC
:
- Prometheus dashboard:
kubectl port-forward svc/kube-prom-stack-kube-prome-prometheus 9090:9090 -n monitoring
. - Grafana dashboards:
kubectl --namespace monitoring port-forward svc/kube-prom-stack-grafana 3000:80
. - Prometheus PVC:
kubectl get pvc -n monitoring
.
Please refer to the 04-setup-prometheus-stack tutorial, for more details about checking Loki
stack deployment status and functionality.
Next, you're going to create the manifests for Loki
stack, and let Flux CD
handle the Helm
release automatically.
In this step, you will use pre-made manifests to create the Loki
Helm release for Flux CD
. Then, Flux
will trigger the Loki
installation process for your DOKS
cluster. Loki
needs a DO Spaces bucket
for storing backups, hence you need to use DO Spaces credentials
. You will learn how to use kubeseal
CLI with Sealed Secrets Controller
to encrypt sensitive
data stored in Kubernetes Secrets
. Then, you will see how the Flux CD HelmRelease
manifest is used to reference
DO Spaces credentials
stored in the Kubernetes Secret
.
Steps to follow:
-
First, change directory where your
Flux CD
Git repository was cloned. Also, please check that the required directory structure for this tutorial is created, and that theFLUXCD_HELM_MANIFESTS_PATH
environment variable is set (please refer to Step 4 - Cloning the Flux CD Git Repository and Preparing the Layout, for details). -
Then, fetch the
Loki
HelmRepository manifest provided by theStarter Kit
Git repository:curl "https://raw.githubusercontent.com/digitalocean/Kubernetes-Starter-Kit-Developers/main/15-automate-with-terraform-flux/assets/manifests/fluxcd/helm/repositories/grafana.yaml" > "${FLUXCD_HELM_MANIFESTS_PATH}/repositories/grafana.yaml"
-
Next,
create
andencrypt
the Kubernetes secret for yourDO Spaces
credentials. Make sure that you have theSealed Secrets
public key exported as mentioned in Exporting the Sealed Secrets Controller Public Key (please replace the<>
placeholders accordingly):SEALED_SECRETS_PUB_KEY="<YOUR_SEALED_SECRETS_PUB_KEY_NAME_HERE>" DO_SPACES_ACCESS_KEY="<YOUR_DO_SPACES_ACCESS_KEY_HERE>" DO_SPACES_SECRET_KEY="<YOUR_DO_SPACES_SECRET_KEY_HERE>" kubectl create secret generic "do-spaces-credentials" \ --namespace flux-system \ --from-literal=access_key_id="${DO_SPACES_ACCESS_KEY}" \ --from-literal=secret_access_key="${DO_SPACES_SECRET_KEY}" \ --dry-run=client -o yaml | kubeseal --cert="${SEALED_SECRETS_PUB_KEY}" \ --format=yaml > "${FLUXCD_HELM_MANIFESTS_PATH}/secrets/do-spaces-credentials-sealed.yaml"
Explanations for the above command:
--namespace
: Namespace where the Kubernetes secret should be created.--from-literal
: Create a Kubernetes secret from a literal value containing the DO Spacesaccess_key_id
andsecret_access_key
. Thedo-spaces-credentials
secret andaccess_key_id/secret_access_key
value is used by the loki-stack-v2.5.1.yaml manifest (spec.valuesFrom
key).--dry-run=client
: Exports the Kubernetes secret on your local machine using standard output (and afterwards, piped tokubeseal
to encrypt the final result).
-
Now, fetch the
Loki
stack HelmRelease manifest provided by theStarter Kit
Git repository:LOKI_CHART_VERSION="2.5.1" curl "https://raw.githubusercontent.com/digitalocean/Kubernetes-Starter-Kit-Developers/main/15-automate-with-terraform-flux/assets/manifests/fluxcd/helm/releases/loki-stack-v${LOKI_CHART_VERSION}.yaml" > "${FLUXCD_HELM_MANIFESTS_PATH}/releases/loki-stack-v${LOKI_CHART_VERSION}.yaml"
-
Then, inspect the downloaded Loki
HelmRelease
manifest using an editor of your choice (preferably withYAML
lint support), and adjust to your needs. For example, you can use VS Code (please make sure to replace the<>
placeholders accordingly, if present):LOKI_CHART_VERSION="2.5.1" code "${FLUXCD_HELM_MANIFESTS_PATH}/releases/loki-stack-v${LOKI_CHART_VERSION}.yaml"
Note: You can see how the
do-spaces-credentials
secret is referenced inside the LokiHelmRelease
manifest, by looking at below snippet:valuesFrom: - kind: Secret name: do-spaces-credentials # Kubernetes secret holding DO Spaces credentials valuesKey: access_key_id # Key from the `do-spaces-credentials` secret, holding the DO Spaces Access Key ID targetPath: loki.config.storage_config.aws.access_key_id # Helm value to override optional: false # Helm release will fail if value is not found - kind: Secret name: do-spaces-credentials valuesKey: secret_access_key # Key from the `do-spaces-credentials` secret, holding the DO Spaces Secret Key targetPath: loki.config.storage_config.aws.secret_access_key optional: false
-
Finally, commit
Git
changes toremote
branch:LOKI_CHART_VERSION="2.5.1" git add "${FLUXCD_HELM_MANIFESTS_PATH}/repositories/grafana.yaml" git add "${FLUXCD_HELM_MANIFESTS_PATH}/releases/loki-stack-v${LOKI_CHART_VERSION}.yaml" git add "${FLUXCD_HELM_MANIFESTS_PATH}/secrets/do-spaces-credentials-sealed.yaml" git commit -am "Adding Loki stack manifests for Flux CD" git push origin
After a few moments, please inspect the Loki HelmRelease
:
flux get helmrelease loki-stack
The output looks similar to:
NAME READY MESSAGE REVISION SUSPENDED
loki-stack True Release reconciliation succeeded 2.5.1 False
Look for the READY
column value - it should say True
. Reconciliation status is displayed in the MESSAGE
column, along with the REVISION
number, which represents the Helm
chart version
. Please bear in mind that some releases take longer to complete (like Prometheus
stack, for example), so please be patient.
Hints:
-
The
MESSAGE
column will displayReconciliation in progress
, as long as theHelmController
is performing the installation for the specifiedHelm
chart. If something goes wrong, you'll get another message stating the reason, so please make sure to check Helm release state. -
You can use the
--watch
flag for example:flux get helmrelease <name> --wait
, to wait until the command finishes. Please bear in mind that in this mode,Flux
will block your terminal prompt until the default timeout of5 minutes
occurs (can be overridden via the--timeout
flag). -
In case something goes wrong, you can search the
Flux
logs, and filterHelmRelease
messages only:flux logs --kind=HelmRelease
Finally, check if the do-spaces-credentials
Kubernetes secret was created as well (then, you can use kubectl get secret do-spaces-credentials -n flux-system -o yaml
for secret contents inspection):
kubectl get secret do-spaces-credentials -n flux-system
Please refer to the 05-setup-loki-stack tutorial, for more details about checking Loki Stack
deployment status and functionality.
Next, you're going to create the manifests and let Flux CD
handle the Velero
Helm release automatically.
In this step, you will use pre-made manifests to create the Velero
Helm release for Flux CD
. Then, Flux
will trigger the Velero
installation process for your DOKS
cluster. Velero
needs a DO Spaces bucket
for storing backups, hence you need to use DO Spaces credentials
. You will learn how to use kubeseal
CLI with Sealed Secrets Controller
to encrypt sensitive
data stored in Kubernetes Secrets
. Then, you will see how the Flux CD HelmRelease
manifest is used to reference
DO API credentials
stored in the Kubernetes Secret
.
Important note:
Before following the steps, make sure that the do-spaces-credentials
sealed secret was provisioned to your DOKS
cluster as detailed in Step 8 - Creating the Loki Stack Helm Release.
Steps to follow:
-
First, change directory where your
Flux CD
Git repository was cloned. Also, please check that the required directory structure for this tutorial is created, and that theFLUXCD_HELM_MANIFESTS_PATH
environment variable is set (please refer to Step 4 - Cloning the Flux CD Git Repository and Preparing the Layout, for details). -
Then, fetch the
Velero
HelmRepository manifest provided by theStarter Kit
Git repository:curl "https://raw.githubusercontent.com/digitalocean/Kubernetes-Starter-Kit-Developers/main/15-automate-with-terraform-flux/assets/manifests/fluxcd/helm/repositories/vmware-tanzu.yaml" > "${FLUXCD_HELM_MANIFESTS_PATH}/repositories/vmware-tanzu.yaml"
-
Next,
create
andencrypt
the Kubernetes secret for VeleroHelmRelease
to consume (DO API TOKEN
). Make sure that you have theSealed Secrets
public key exported as mentioned in Exporting the Sealed Secrets Controller Public Key (please replace the<>
placeholders accordingly):SEALED_SECRETS_PUB_KEY="<YOUR_SEALED_SECRETS_PUB_KEY_NAME_HERE>" DO_API_TOKEN="<YOUR_DO_API_TOKEN_HERE>" kubectl create secret generic "do-api-credentials" \ --namespace flux-system \ --from-literal=do_api_token="${DO_API_TOKEN}" \ --dry-run=client -o yaml | kubeseal --cert="${SEALED_SECRETS_PUB_KEY}" \ --format=yaml > "${FLUXCD_HELM_MANIFESTS_PATH}/secrets/do-api-credentials-sealed.yaml"
Explanations for the above command:
--namespace
: Namespace where the Kubernetes secret should be created.--from-literal
: Create a Kubernetes secret from a literal value containing the DO API token. Thedo-credentials
secret anddo_api_token
value is used by the velero-v2.27.3.yaml manifest (spec.valuesFrom
key).--dry-run=client
: Exports the Kubernetes secret on your local machine using standard output (and afterwards, piped tokubeseal
to encrypt the final result).
-
Now, fetch the
Loki
stack HelmRelease manifest provided by theStarter Kit
Git repository:VELERO_CHART_VERSION="2.27.3" curl "https://raw.githubusercontent.com/digitalocean/Kubernetes-Starter-Kit-Developers/main/15-automate-with-terraform-flux/assets/manifests/fluxcd/helm/releases/velero-v${VELERO_CHART_VERSION}.yaml" > "${FLUXCD_HELM_MANIFESTS_PATH}/releases/velero-v${VELERO_CHART_VERSION}.yaml"
-
Then, inspect the downloaded Velero
HelmRelease
manifest using an editor of your choice (preferably withYAML
lint support), and adjust to your needs. For example, you can use VS Code (please make sure to replace the<>
placeholders accordingly, if present):VELERO_CHART_VERSION="2.27.3" code "${FLUXCD_HELM_MANIFESTS_PATH}/releases/velero-v${VELERO_CHART_VERSION}.yaml"
Notes:
-
You can see how
do-api-credentials
anddo-spaces-credentials
secrets are referenced inside the VeleroHelmRelease
manifest, by looking at below snippet:valuesFrom: - kind: Secret name: do-api-credentials # Kubernetes secret holding DO API token valuesKey: do_api_token # Key from the `do-api-credentials` secret, holding the DO API token targetPath: configuration.extraEnvVars.DIGITALOCEAN_TOKEN # Helm value to override optional: false # Helm release will fail if value is not found - kind: Secret name: do-spaces-credentials # Kubernetes secret holding DO Spaces credentials valuesKey: access_key_id # Key from the `do-spaces-credentials` secret, holding the DO Spaces Access Key ID targetPath: configuration.extraEnvVars.AWS_ACCESS_KEY_ID optional: false - kind: Secret name: do-spaces-credentials valuesKey: secret_access_key # Key from the `do-spaces-credentials` secret, holding the DO Spaces Secret Key targetPath: configuration.extraEnvVars.AWS_SECRET_ACCESS_KEY optional: false
-
Please bear in mind that the above secret data is placed inside environment variables (
configuration.extraEnvVars
), so values will be visible in clear text if you describe theVelero
deployment (onproduction
environments you can restrictvelero namespace
access viaRBAC
, for example).kubectl describe deployment velero -n velero | grep AWS_ACCESS_KEY_ID
-
-
Finally, commit
Git
changes toremote
branch:VELERO_CHART_VERSION="2.27.3" git add "${FLUXCD_HELM_MANIFESTS_PATH}/repositories/vmware-tanzu.yaml" git add "${FLUXCD_HELM_MANIFESTS_PATH}/releases/velero-v${VELERO_CHART_VERSION}.yaml" git add "${FLUXCD_HELM_MANIFESTS_PATH}/secrets/do-api-credentials-sealed.yaml" git commit -am "Adding Velero manifests for Flux CD" git push origin
After a few moments, please inspect the Velero HelmRelease
:
flux get helmrelease velero-stack
The output looks similar to:
NAME READY MESSAGE REVISION SUSPENDED
velero-stack True Release reconciliation succeeded 2.27.3 False
Look for the READY
column value - it should say True
. Reconciliation status is displayed in the MESSAGE
column, along with the REVISION
number, which represents the Helm
chart version
. Please bear in mind that some releases take longer to complete (like Prometheus
stack, for example), so please be patient.
Hints:
-
The
MESSAGE
column will displayReconciliation in progress
, as long as theHelmController
is performing the installation for the specifiedHelm
chart. If something goes wrong, you'll get another message stating the reason, so please make sure to check Helm release state. -
You can use the
--watch
flag for example:flux get helmrelease <name> --wait
, to wait until the command finishes. Please bear in mind that in this mode,Flux
will block your terminal prompt until the default timeout of5 minutes
occurs (can be overridden via the--timeout
flag). -
In case something goes wrong, you can search the
Flux
logs, and filterHelmRelease
messages only:flux logs --kind=HelmRelease
Finally, check if the do-api-credentials
Kubernetes secret was created as well (then, you can use kubectl get secret do-api-credentials -n flux-system -o yaml
for secret contents inspection):
kubectl get secret do-api-credentials -n flux-system
Please refer to the Velero tutorial, for more details about checking Velero
deployment status and functionality.
In this tutorial, you learned the automation basics for a GitOps
based setup. You learned about Terraform
modules, and how to re-use configuration to provision the required infrastructure, targeting DOKS
cluster and Flux CD
.
Then, you configured Flux CD
to perform Helm
releases for you automatically by creating specific manifests, and deploy all the Starter Kit
components in a GitOps
fashion. Finally, you applied security
best practices as well, by making use of Sealed Secrets
to encrypt sensitive
data for your applications
to use (Helm
releases).
Going further, Flux CD
supports other interesting Controllers
as well, which can be configured and enabled, like:
- Notification Controller - specialized in handling inbound and outbound events for
Slack
, etc. - Image Automation Controller - updates a
Git
repository when new container images are available.
You can visit the official Flux CD Guides page for more interesting stuff and ideas, like how to structure your Git
repositories, as well as application manifests
for multi-cluster
and multi-environment
setups.