Our setup is using Google Secret Manager as we are already in the Google Cloud platform. With Jenkins-X 3, it is easier to manage secrets without even knowing the internal details about the secret storage. The Secrets guide should already be enough but I’d like to share how we set it up in our project.
External Secrets
Under the hood, Jenkins-X uses external secrets to sync secrets from storage into Kubernetes secrets.
Create secret into a namespace
Let’s start creating a secret into a specific namespace, for example: jx-staging
. In Jenkins-X 3, creating a secret is the same as creating any kubernetes resource. In your cluster git repository, add the following directory structure at the repo root directory.
charts\
- staging-secrets\
- templates\
- app-mongodb-staging.yaml
- Chart.yaml
Here, we are trying to create a secret for our application’s MongoDB replica set. We name it staging-secrets
because we are planning to add more secrets to it for other applications and it is a good way to group these resources.
The content of app-mongodb-staging.yaml
looks like this:
# app-mongodb-staging.yaml
apiVersion: v1
data:
mongodb-password: ""
mongodb-root-password: ""
mongodb-replica-set-key: ""
kind: Secret
metadata:
name: app-mongodb-staging
type: Opaque
We don’t have to put the content into the file. We can populate it later.
Next, we need to populate Chart.yaml
. It looks like this.
# Chart.yaml
apiVersion: v1
description: A Helm chart for staging secrets
name: staging-secrets
version: 0.0.1
appVersion: 0.0.1
icon: https://avatars.githubusercontent.com/u/114853
home: https://github.com/lysender
Now, we are ready to use our charts. Add the following lines into the releases
section of helmfile.yaml
which is located at the root of the cluster git repository.
# helmfile.yaml
releases:
- chart: ./charts/staging-secrets
name: staging-secrets
namespace: jx-staging
When ready, create a pull request and merge it to apply the changes.
This whole process does not create the secret yet. It creates the external secret which can be listed by running:
kubectl get es -n jx-staging
You should be able to see app-mongodb-staging
entry. It should also show an error status saying the secret is not yet populated or something.
Populate the value by running:
# Switch namespace first
jx ns jx-staging
# Edit secret
jx secret edit -f app-mongodb-staging
You should be prompted to enter the 3 secret values for app-mongodb-staging
. It should get synced after 1 minute.
# List external secrets
kubectl get es -n jx-staging
# List secrets synced by external secrets
kubectl get secrets -n jx-staging
You should see the secret and the contents after this. With secret already synced, we can use this secret in our MongoDB helm chart.
Replicate a secret into all namespaces
If your requirement is to have a secret replicated into all namespaces, it is easy to do with Jenkins-X 3. In the following example, we wanted to create a secret for our MongoDB for preview environments. Since we cannot target a specific namespace for preview environment, we used the secret replication to solve this issue.
This means that the secrets replicated to staging and production would be useless and costs us more if we are using something like Google Secret Manager. Let me know if you know a trick for creating temporary secrets for preview environments.
We need to add another chart under charts
directory and we will call it development-secrets
charts\
- development-secrets\
- templates\
- app-mongodb-development.yaml
- Chart.yaml
- staging-secrets\
...
The content for app-mongodb-development.yaml
looks like this:
# app-mongodb-development.yaml
apiVersion: v1
data:
mongodb-password: ""
mongodb-root-password: ""
mongodb-replica-set-key: ""
kind: Secret
metadata:
name: app-mongodb-development
labels:
secret.jenkins-x.io/replica-source: "true"
type: Opaque
It’s almost the same as the staging secrets. We just added the label
secret.jenkins-x.io/replica-source: "true"
to enable secret replication.
We will add it to the jx
namespace instead as it will be replicated to all namespaces anyway.
releases:
- chart: ./charts/development-secrets
name: development-secrets
namespace: jx
- chart: ./charts/staging-secrets
name: staging-secrets
namespace: jx-staging
Once merged and applied, populate the secret starting from the jx
namespace:
# Switch namespace
jx ns jx
# Populate secret now
jx secret edit -f app-mongodb-development
You will be prompted multiple times depending on how many namespaces the secret is replicated into. Just enter the same value every time.
That’s it!
If you know a trick on how to create a temporary secret to be used only in preview environments, do let me know. This will save us some Google Secret Manager cost.
Featured image by PhotoMIX Company.