Generating the MongoDB Kubernetes Secret using External Secrets Operator – Securing and Testing Your CI/CD Pipeline

Generating the MongoDB Kubernetes Secret using External Secrets Operator – Securing and Testing Your CI/CD Pipeline

To generate the mongodb-creds secret, we would need to create the following resources:
• A Secret resource – This is a standard Kubernetes Secret resource containing the service account credentials for Kubernetes to connect with GCP Secret Manager.
• A ClusterSecretStore resource – This resource contains configuration for connecting with the secret store (GCP Secret Manager in this case) and uses the Secret resource for the service account credentials.
• An ExternalSecret resource – This resource contains configuration to generate the required Kubernetes Secret (mongodb-creds) out of the extracted Secret from the secret store.

So, let’s go ahead and define the Secret resource first:

To create the Secret resource, we first need to create a GCP service account to interact with Secret Manager using the following commands:
$ cd ~
$ gcloud iam service-accounts create external-secrets

As we’re following the principle of least privilege, we will add the following role-binding to provide access only to the external-secrets secret, as follows:
$ gcloud secrets add-iam-policy-binding external-secrets \
–member “serviceAccount:external-secrets@$PROJECT_ID.iam.gserviceaccount.com” \ –role “roles/secretmanager.secretAccessor”

Now, let’s generate the service account key file using the following command:
$ gcloud iam service-accounts keys create key.json \
–iam-account=external-secrets@$PROJECT_ID.iam.gserviceaccount.com

Now, copy the contents of the key.json file into a new GitHub Actions secret called GCP_SM_ CREDENTIALS. We will use GitHub Actions to set this value during runtime dynamically; therefore, the following secret manifest will contain a placeholder:
apiVersion: v1
data:
secret-access-credentials: SECRET_ACCESS_CREDS_PH
kind: Secret
metadata:
name: gcpsm-secret
type: Opaque

Let’s look at the ClusterSecretStore resource next:
apiVersion: external-secrets.io/v1alpha1
kind: ClusterSecretStore
metadata:
name: gcp-backend
spec:
provider:
gcpsm:
auth:
secretRef:
secretAccessKeySecretRef:
name: gcpsm-secret
key: secret-access-credentials
projectID: PROJECT_ID_PH

The manifest defines the following:
• A ClusterSecretStore resource called gcp-backend
• A provider configuration of the gcpsm type using auth information in the gcpsm-secret secret we defined before

Now, let’s look at the ExternalSecret resource manifest:
apiVersion: external-secrets.io/v1alpha1
kind: ExternalSecret
metadata:
name: mongodb-creds
namespace: blog-app
spec:
secretStoreRef:
kind: SecretStore
name: gcp-backend
target:
name: mongodb-creds
data:

  • secretKey: MONGO_INITDB_ROOT_USERNAME remoteRef:
    key: external-secrets
    property: MONGO_INITDB_ROOT_USERNAME
  • secretKey: MONGO_INITDB_ROOT_PASSWORD remoteRef:
    key: external-secrets
    property: MONGO_INITDB_ROOT_PASSWORD

The manifest defines an ExternalSecret resource with the following specs:
• It is named mongodb-creds in the blog-app namespace.
• It refers to the gcp-backend ClusterSecretStore that we defined.
• It maps MONGO_INITDB_ROOT_USERNAME from the external-secrets Secret Manager secret to the MONGO_INITDB_ROOT_USERNAME key of the mongodb-creds Kubernetes secret. It does the same for MONGO_INITDB_ROOT_PASSWORD.

Now, let’s deploy these resources by using the following commands:
$ cd ~/mdo-environments
$ cp ~/modern-devops/ch13/configure-external-secrets/app.tf terraform/app.tf $ cp ~/modern-devops/ch13/configure-external-secrets/gcpsm-secret.yaml \ manifests/argocd/
$ cp ~/modern-devops/ch13/configure-external-secrets/mongodb-creds-external.yaml \ manifests/blog-app/
$ cp -r ~/modern-devops/ch13/configure-external-secrets/.github .
$ git add –all
$ git commit -m “Configure External Secrets”
$ git push

This should trigger a GitHub Actions workflow again, and soon, we should seeClusterSecretStore and ExternalSecret created. To check that, run the following commands:
$ kubectl get secret gcpsm-secret
NAME TYPE DATA AGE
gcpsm-secret Opaque 1 1m
$ kubectl get clustersecretstore gcp-backend
NAME AGE STATUS CAPABILITIES READY
gcp-backend 19m Valid ReadWrite True
$ kubectl get externalsecret -n blog-app mongodb-creds
NAME STORE REFRESHINTERVAL STATUS READY
mongodb-creds gcp-backend 1h0m0s SecretSynced True
$ kubectl get secret -n blog-app mongodb-creds
NAME TYPE DATA AGE
mongodb-creds Opaque 2 4m45s

The same should be reflected in the blog-app application on Argo CD, and the application should come up clean, as shown in the following screenshot:

Figure 13.8 – blog-app showing as Healthy

You can then access the application by getting the frontend service external IP using the following command:
$ kubectl get svc -n blog-app frontend
NAME TYPE EXTERNAL-IP PORT(S) AGE frontend LoadBalancer 34.122.58.73 80:30867/TCP 153m

You can access the application by visiting http:// from a browser:

Figure 13.9 – Blog App home page

And as we can see, we can access the Blog App successfully. That is proper secret management, as we did not store the secret in the source code repository (Git). We did not view or log the secret while applying it, meaning there is no trace of this secret anywhere in the logs, and only the application or people who have access to the namespace where this application is running can access it. Now, let’s look at another crucial aspect: testing your application.

Leave a Reply

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



          Terms of Use | About Breannaworld | Privacy Policy | Cookies | Accessibility Help | Contact Breannaworld