jenkins-x, kubernetes

Jenkins-X 3 and Helm – Creating Secrets

Jenkins-X 3 and Helm – Creating Secrets

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.

Leave a reply

Your email address will not be published. Required fields are marked *